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,6 +14,7 @@ public class RNFetchBlobConfig {
14 14
     public String appendExt;
15 15
     public ReadableMap addAndroidDownloads;
16 16
     public Boolean trusty;
17
+    public String key;
17 18
 
18 19
     RNFetchBlobConfig(ReadableMap options) {
19 20
         if(options == null)
@@ -25,6 +26,7 @@ public class RNFetchBlobConfig {
25 26
         if(options.hasKey("addAndroidDownloads")) {
26 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,25 +27,25 @@ public class RNFetchBlobFileHandler extends FileAsyncHttpResponseHandler {
27 27
     String mTaskId;
28 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 32
         this.onResponse = onResponse;
33 33
         this.mTaskId = taskId;
34 34
         this.mConfig = config;
35 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 37
             this.isValid = false;
38 38
         }
39 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 43
         if(config.path != null)
44 44
             return config.path;
45 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 47
         else
48
-            return RNFetchBlobFS.getTmpPath(ctx, taskId);
48
+            return RNFetchBlobFS.getTmpPath(ctx, key);
49 49
     }
50 50
 
51 51
     @Override

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

@@ -20,6 +20,7 @@ import com.loopj.android.http.MySSLSocketFactory;
20 20
 
21 21
 import java.io.File;
22 22
 import java.security.KeyStore;
23
+import java.security.MessageDigest;
23 24
 
24 25
 import cz.msebera.android.httpclient.HttpEntity;
25 26
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
@@ -76,6 +77,20 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
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 94
     @Override
80 95
     public void run() {
81 96
 
@@ -107,6 +122,17 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
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 136
         try {
111 137
 
112 138
             req = new AsyncHttpClient();
@@ -141,7 +167,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
141 167
 
142 168
             // create handler
143 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 171
                 // if path format invalid, throw error
146 172
                 if (!((RNFetchBlobFileHandler)handler).isValid) {
147 173
                     callback.invoke("RNFetchBlob fetch error, configuration path `"+ options.path  +"` is not a valid path.");

+ 7
- 1
src/index.js View File

@@ -79,6 +79,12 @@ function wrap(path:string):string {
79 79
  *                   If this property has a valid string format, resonse data
80 80
  *                   will be saved to specific file path. Default string format
81 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 89
  * @return {function} This method returns a `fetch` method instance.
84 90
  */
@@ -125,7 +131,7 @@ function fetch(...args:any):Promise {
125 131
       else {
126 132
         let respType = 'base64'
127 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 135
           respType = 'path'
130 136
           if(options.session)
131 137
             session(options.session).add(data)