Browse Source

Optimize network traffic (use cache first if requested)

This is a proof-of-concept of how to implement it.
Tests are needed.
Also, I believe there's an overlap with fileCache, which needs some figuring out.
Juan B. Rodriguez 8 years ago
parent
commit
586d81dfff

+ 2
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobConfig.java View File

14
     public String appendExt;
14
     public String appendExt;
15
     public ReadableMap addAndroidDownloads;
15
     public ReadableMap addAndroidDownloads;
16
     public Boolean trusty;
16
     public Boolean trusty;
17
+    public String key;
17
 
18
 
18
     RNFetchBlobConfig(ReadableMap options) {
19
     RNFetchBlobConfig(ReadableMap options) {
19
         if(options == null)
20
         if(options == null)
25
         if(options.hasKey("addAndroidDownloads")) {
26
         if(options.hasKey("addAndroidDownloads")) {
26
             this.addAndroidDownloads = options.getMap("addAndroidDownloads");
27
             this.addAndroidDownloads = options.getMap("addAndroidDownloads");
27
         }
28
         }
29
+        this.key = options.hasKey("key") ? options.getString("key") : null;
28
     }
30
     }
29
 
31
 
30
 }
32
 }

+ 6
- 6
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFileHandler.java View File

27
     String mTaskId;
27
     String mTaskId;
28
     RNFetchBlobConfig mConfig;
28
     RNFetchBlobConfig mConfig;
29
 
29
 
30
-    RNFetchBlobFileHandler(ReactApplicationContext ctx, String taskId, RNFetchBlobConfig config, Callback onResponse) {
31
-        super(new File( RNFetchBlobFileHandler.getFilePath(ctx, taskId, config)), false, false);
30
+    RNFetchBlobFileHandler(ReactApplicationContext ctx, String taskId, String key, RNFetchBlobConfig config, Callback onResponse) {
31
+        super(new File( RNFetchBlobFileHandler.getFilePath(ctx, taskId, key, config)), false, false);
32
         this.onResponse = onResponse;
32
         this.onResponse = onResponse;
33
         this.mTaskId = taskId;
33
         this.mTaskId = taskId;
34
         this.mConfig = config;
34
         this.mConfig = config;
35
         this.mCtx = ctx;
35
         this.mCtx = ctx;
36
-        if(!new File(RNFetchBlobFileHandler.getFilePath(ctx, taskId, config)).isFile()) {
36
+        if(!new File(RNFetchBlobFileHandler.getFilePath(ctx, taskId, key, config)).isFile()) {
37
             this.isValid = false;
37
             this.isValid = false;
38
         }
38
         }
39
         this.isValid = true;
39
         this.isValid = true;
40
     }
40
     }
41
 
41
 
42
-    static String getFilePath(ReactApplicationContext ctx, String taskId, RNFetchBlobConfig config) {
42
+    static String getFilePath(ReactApplicationContext ctx, String taskId, String key, RNFetchBlobConfig config) {
43
         if(config.path != null)
43
         if(config.path != null)
44
             return config.path;
44
             return config.path;
45
         else if(config.fileCache && config.appendExt != null)
45
         else if(config.fileCache && config.appendExt != null)
46
-            return RNFetchBlobFS.getTmpPath(ctx, taskId) + "." + config.appendExt;
46
+            return RNFetchBlobFS.getTmpPath(ctx, key) + "." + config.appendExt;
47
         else
47
         else
48
-            return RNFetchBlobFS.getTmpPath(ctx, taskId);
48
+            return RNFetchBlobFS.getTmpPath(ctx, key);
49
     }
49
     }
50
 
50
 
51
     @Override
51
     @Override

+ 27
- 1
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

20
 
20
 
21
 import java.io.File;
21
 import java.io.File;
22
 import java.security.KeyStore;
22
 import java.security.KeyStore;
23
+import java.security.MessageDigest;
23
 
24
 
24
 import cz.msebera.android.httpclient.HttpEntity;
25
 import cz.msebera.android.httpclient.HttpEntity;
25
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
26
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
76
         }
77
         }
77
     }
78
     }
78
 
79
 
80
+    public static String getMD5(String input) {
81
+        MessageDigest md = MessageDigest.getInstance("MD5");
82
+        md.update(input.getBytes());
83
+        byte[] digest = md.digest();
84
+        
85
+        StringBuffer sb = new StringBuffer();
86
+        
87
+        for (byte b : digest) {
88
+            sb.append(String.format("%02x", b & 0xff))
89
+        }
90
+
91
+        return sb.toString();
92
+    }
93
+
79
     @Override
94
     @Override
80
     public void run() {
95
     public void run() {
81
 
96
 
107
 
122
 
108
         }
123
         }
109
 
124
 
125
+        String key = this.taskId;
126
+        if (this.options.key != null) {
127
+            key = RNFetchBlobReq.getMD5(this.options.key);
128
+
129
+            File file = new File(RNFetchBlobFileHandler.getFilePath(ctx, taskId, key, this.options))
130
+            if (file.exists()) {
131
+               callback.invoke(null, file.getAbsolutePath());
132
+               return;
133
+            }
134
+        }
135
+
110
         try {
136
         try {
111
 
137
 
112
             req = new AsyncHttpClient();
138
             req = new AsyncHttpClient();
141
 
167
 
142
             // create handler
168
             // create handler
143
             if(options.fileCache || options.path != null) {
169
             if(options.fileCache || options.path != null) {
144
-                handler = new RNFetchBlobFileHandler(ctx, taskId, options, callback);
170
+                handler = new RNFetchBlobFileHandler(ctx, taskId, key, options, callback);
145
                 // if path format invalid, throw error
171
                 // if path format invalid, throw error
146
                 if (!((RNFetchBlobFileHandler)handler).isValid) {
172
                 if (!((RNFetchBlobFileHandler)handler).isValid) {
147
                     callback.invoke("RNFetchBlob fetch error, configuration path `"+ options.path  +"` is not a valid path.");
173
                     callback.invoke("RNFetchBlob fetch error, configuration path `"+ options.path  +"` is not a valid path.");

+ 7
- 1
src/index.js View File

79
  *                   If this property has a valid string format, resonse data
79
  *                   If this property has a valid string format, resonse data
80
  *                   will be saved to specific file path. Default string format
80
  *                   will be saved to specific file path. Default string format
81
  *                   is : `RNFetchBlob-file://path-to-file`
81
  *                   is : `RNFetchBlob-file://path-to-file`
82
+ *         @property {string} key
83
+ *                   If this property is set, it will be converted to md5, to
84
+ *                   check if a file with this name exists.
85
+ *                   If it exists, the absolute path is returned (no network 
86
+ *                   activity takes place )
87
+ *                   If it doesn't exist, the file is downloaded as usual
82
  *
88
  *
83
  * @return {function} This method returns a `fetch` method instance.
89
  * @return {function} This method returns a `fetch` method instance.
84
  */
90
  */
125
       else {
131
       else {
126
         let respType = 'base64'
132
         let respType = 'base64'
127
         // response data is saved to storage
133
         // response data is saved to storage
128
-        if(options.path || options.fileCache || options.addAndroidDownloads) {
134
+        if(options.path || options.fileCache || options.addAndroidDownloads || options.key) {
129
           respType = 'path'
135
           respType = 'path'
130
           if(options.session)
136
           if(options.session)
131
             session(options.session).add(data)
137
             session(options.session).add(data)