Browse Source

Merge branch '0.8.0' into issue_44

Ben Hsieh 8 years ago
parent
commit
73d2196357

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

171
     }
171
     }
172
 
172
 
173
 }
173
 }
174
-

+ 32
- 1
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java View File

20
 
20
 
21
 import okhttp3.MediaType;
21
 import okhttp3.MediaType;
22
 import okhttp3.RequestBody;
22
 import okhttp3.RequestBody;
23
+import okhttp3.FormBody;
23
 import okio.Buffer;
24
 import okio.Buffer;
24
 import okio.BufferedSink;
25
 import okio.BufferedSink;
25
 import okio.ForwardingSink;
26
 import okio.ForwardingSink;
71
             case SingleFile:
72
             case SingleFile:
72
                 writeOctetData(sink);
73
                 writeOctetData(sink);
73
                 break;
74
                 break;
75
+			case Encoded:
76
+				writeEncodedData(sink);
77
+				break;
74
         }
78
         }
75
         buffer.flush();
79
         buffer.flush();
76
     }
80
     }
77
 
81
 
78
-    private void writeFormData(BufferedSink sink) throws IOException {
82
+	private void writeFormData(BufferedSink sink) throws IOException {
79
         String boundary = "RNFetchBlob-" + mTaskId;
83
         String boundary = "RNFetchBlob-" + mTaskId;
80
         ArrayList<FormField> fields = countFormDataLength();
84
         ArrayList<FormField> fields = countFormDataLength();
81
         ReactApplicationContext ctx = RNFetchBlob.RCTContext;
85
         ReactApplicationContext ctx = RNFetchBlob.RCTContext;
184
 
188
 
185
     }
189
     }
186
 
190
 
191
+
192
+	/**
193
+     * Write form-encoded data to request body
194
+     * @param sink
195
+     */
196
+	 // This is NOT working since sink.write, creates a Transfer-Encoding: chunked
197
+	 // header, which is not expected from servers
198
+	private void writeEncodedData(BufferedSink sink) throws IOException {
199
+		FormBody.Builder body = new FormBody.Builder();
200
+
201
+		// String[] pairs = rawBody.split("&");
202
+		// for ( String pair : pairs ) {
203
+		// 	String[] kv = pair.split("=");
204
+		// 	body.add(kv[0], kv[1]);
205
+		// }
206
+		// body.build().writeTo(sink);
207
+
208
+		// String header = "Content-Disposition: form-data; \r\n";
209
+		// String header = "Content-Type: application/x-www-form-urlencoded\r\n\r\n";
210
+		// sink.write(header.getBytes());
211
+		// byte[] fieldData = field.data.getBytes();
212
+		// bytesWritten += fieldData.length;
213
+		sink.write(rawBody.getBytes());
214
+
215
+
216
+	}
217
+
187
     /**
218
     /**
188
      * Pipe input stream to request body output stream
219
      * Pipe input stream to request body output stream
189
      * @param stream    The input stream
220
      * @param stream    The input stream

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

11
     public static final String FILE_PREFIX = "RNFetchBlob-file://";
11
     public static final String FILE_PREFIX = "RNFetchBlob-file://";
12
     public static final MediaType MIME_OCTET = MediaType.parse("application/octet-stream");
12
     public static final MediaType MIME_OCTET = MediaType.parse("application/octet-stream");
13
     public static final MediaType MIME_MULTIPART = MediaType.parse("multipart/form-data");
13
     public static final MediaType MIME_MULTIPART = MediaType.parse("multipart/form-data");
14
+	public static final MediaType MIME_ENCODED = MediaType.parse("application/x-www-form-urlencoded");
14
     public static final String FILE_PREFIX_BUNDLE_ASSET = "bundle-assets://";
15
     public static final String FILE_PREFIX_BUNDLE_ASSET = "bundle-assets://";
15
     public static final String FILE_PREFIX_CONTENT = "content://";
16
     public static final String FILE_PREFIX_CONTENT = "content://";
16
-
17
 }
17
 }

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

799
     }
799
     }
800
 
800
 
801
 }
801
 }
802
-
803
-

+ 37
- 14
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

8
 import android.database.Cursor;
8
 import android.database.Cursor;
9
 import android.net.Uri;
9
 import android.net.Uri;
10
 import android.util.Base64;
10
 import android.util.Base64;
11
+import android.util.Log;
11
 
12
 
12
 import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
13
 import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
13
 import com.RNFetchBlob.Response.RNFetchBlobFileResp;
14
 import com.RNFetchBlob.Response.RNFetchBlobFileResp;
34
 import okhttp3.RequestBody;
35
 import okhttp3.RequestBody;
35
 import okhttp3.Response;
36
 import okhttp3.Response;
36
 import okhttp3.ResponseBody;
37
 import okhttp3.ResponseBody;
38
+import okhttp3.FormBody;
37
 
39
 
38
 /**
40
 /**
39
  * Created by wkh237 on 2016/6/21.
41
  * Created by wkh237 on 2016/6/21.
42
 
44
 
43
     enum RequestType  {
45
     enum RequestType  {
44
         Form,
46
         Form,
47
+		Encoded,
45
         SingleFile,
48
         SingleFile,
46
         WithoutBody,
49
         WithoutBody,
47
         Others
50
         Others
85
         else
88
         else
86
             responseType = ResponseType.KeepInMemory;
89
             responseType = ResponseType.KeepInMemory;
87
 
90
 
88
-        if (body != null)
91
+        if (body != null && headers.hasKey("content-type") && "application/x-www-form-urlencoded".equals(headers.getString("content-type")))
92
+			requestType = RequestType.Encoded;
93
+		else if (body != null)
89
             requestType = RequestType.SingleFile;
94
             requestType = RequestType.SingleFile;
90
         else if (arrayBody != null)
95
         else if (arrayBody != null)
91
             requestType = RequestType.Form;
96
             requestType = RequestType.Form;
135
 
140
 
136
         // find cached result if `key` property exists
141
         // find cached result if `key` property exists
137
         String cacheKey = this.taskId;
142
         String cacheKey = this.taskId;
138
-//        if (this.options.key != null) {
139
-//            cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
140
-//            if (cacheKey == null) {
141
-//                cacheKey = this.taskId;
142
-//            }
143
-//
144
-//            File file = new File(RNFetchBlobFS.getTmpPath(ctx, cacheKey));
145
-//            if (file.exists()) {
146
-//                callback.invoke(null, file.getAbsolutePath());
147
-//                return;
148
-//            }
149
-//        }
143
+		String ext = this.options.appendExt != "" ? "." + this.options.appendExt : "";
144
+
145
+       	if (this.options.key != null) {
146
+           cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
147
+           if (cacheKey == null) {
148
+               cacheKey = this.taskId;
149
+           }
150
+
151
+           File file = new File(RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey) + ext);
152
+
153
+           if (file.exists()) {
154
+               callback.invoke(null, file.getAbsolutePath());
155
+               return;
156
+           }
157
+       }
150
 
158
 
151
         if(this.options.path != null)
159
         if(this.options.path != null)
152
             this.destPath = this.options.path;
160
             this.destPath = this.options.path;
153
         else if(this.options.fileCache == true)
161
         else if(this.options.fileCache == true)
154
-            this.destPath = RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey);
162
+            this.destPath = RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey) + ext;
155
 
163
 
156
         OkHttpClient.Builder clientBuilder;
164
         OkHttpClient.Builder clientBuilder;
157
 
165
 
197
                             MediaType.parse("multipart/form-data; boundary=RNFetchBlob-" + taskId)
205
                             MediaType.parse("multipart/form-data; boundary=RNFetchBlob-" + taskId)
198
                     ));
206
                     ));
199
                     break;
207
                     break;
208
+				case Encoded:
209
+					// rawRequestBody has an expected format of
210
+					// key1=value1&key2=value&...
211
+					FormBody.Builder formBuilder = new FormBody.Builder();
212
+
213
+					String[] pairs = rawRequestBody.split("&");
214
+					for ( String pair : pairs ) {
215
+						String[] kv = pair.split("=");
216
+						formBuilder.add(kv[0], kv[1]);
217
+					}
218
+
219
+					RequestBody body = formBuilder.build();
220
+
221
+					builder.method(method, body);
222
+					break;
200
                 case WithoutBody:
223
                 case WithoutBody:
201
                     builder.method(method, null);
224
                     builder.method(method, null);
202
                     break;
225
                     break;

+ 46
- 37
src/ios/RNFetchBlob/RNFetchBlob.m View File

62
                   form:(NSArray *)form
62
                   form:(NSArray *)form
63
                   callback:(RCTResponseSenderBlock)callback)
63
                   callback:(RCTResponseSenderBlock)callback)
64
 {
64
 {
65
-    
65
+
66
     [RNFetchBlobReqBuilder buildMultipartRequest:options taskId:taskId method:method url:url headers:headers form:form onComplete:^(NSURLRequest *req, long bodyLength) {
66
     [RNFetchBlobReqBuilder buildMultipartRequest:options taskId:taskId method:method url:url headers:headers form:form onComplete:^(NSURLRequest *req, long bodyLength) {
67
         // send HTTP request
67
         // send HTTP request
68
         RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
68
         RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
69
         [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
69
         [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
70
         utils = nil;
70
         utils = nil;
71
     }];
71
     }];
72
-    
72
+
73
 }
73
 }
74
 
74
 
75
 // Fetch blob data request
75
 // Fetch blob data request
80
                   headers:(NSDictionary *)headers
80
                   headers:(NSDictionary *)headers
81
                   body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
81
                   body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
82
 {
82
 {
83
-    [RNFetchBlobReqBuilder buildOctetRequest:options taskId:taskId method:method url:url headers:headers body:body onComplete:^(NSURLRequest *req, long bodyLength) {
84
-        // send HTTP request
85
-        RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
86
-        [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
87
-        utils = nil;
88
-    }];
89
-    
83
+	NSString *cType = [headers valueForKey:"content-type"]
84
+	if (cType != nil && cType == @"application/x-www-form-urlencoded") {
85
+		[RNFetchBlobReqBuilder buildEncodedRequest:options taskId:taskId method:method url:url headers:headers body:body onComplete:^(NSURLRequest *req, long bodyLength) {
86
+	        // send HTTP request
87
+	        RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
88
+	        [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
89
+	        utils = nil;
90
+	    }];
91
+	} else {
92
+		[RNFetchBlobReqBuilder buildOctetRequest:options taskId:taskId method:method url:url headers:headers body:body onComplete:^(NSURLRequest *req, long bodyLength) {
93
+	        // send HTTP request
94
+	        RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
95
+	        [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
96
+	        utils = nil;
97
+	    }];
98
+	}
90
 }
99
 }
91
 
100
 
92
 RCT_EXPORT_METHOD(createFile:(NSString *)path data:(NSString *)data encoding:(NSString *)encoding callback:(RCTResponseSenderBlock)callback) {
101
 RCT_EXPORT_METHOD(createFile:(NSString *)path data:(NSString *)data encoding:(NSString *)encoding callback:(RCTResponseSenderBlock)callback) {
93
-    
102
+
94
     NSFileManager * fm = [NSFileManager defaultManager];
103
     NSFileManager * fm = [NSFileManager defaultManager];
95
     NSData * fileContent = nil;
104
     NSData * fileContent = nil;
96
-    
105
+
97
     if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
106
     if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
98
         fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
107
         fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
99
     }
108
     }
103
     else {
112
     else {
104
         fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
113
         fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
105
     }
114
     }
106
-    
115
+
107
     BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
116
     BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
108
     if(success == YES)
117
     if(success == YES)
109
         callback(@[[NSNull null]]);
118
         callback(@[[NSNull null]]);
110
     else
119
     else
111
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
120
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
112
-    
121
+
113
 }
122
 }
114
 
123
 
115
 // method for create file with ASCII content
124
 // method for create file with ASCII content
116
 RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
125
 RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
117
-    
126
+
118
     NSFileManager * fm = [NSFileManager defaultManager];
127
     NSFileManager * fm = [NSFileManager defaultManager];
119
     NSMutableData * fileContent = [NSMutableData alloc];
128
     NSMutableData * fileContent = [NSMutableData alloc];
120
     // prevent stack overflow, alloc on heap
129
     // prevent stack overflow, alloc on heap
130
         callback(@[[NSNull null]]);
139
         callback(@[[NSNull null]]);
131
     else
140
     else
132
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
141
         callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
133
-    
142
+
134
 }
143
 }
135
 
144
 
136
 
145
 
139
     BOOL exists = NO;
148
     BOOL exists = NO;
140
     exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory: &isDir];
149
     exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory: &isDir];
141
     callback(@[@(exists), @(isDir)]);
150
     callback(@[@(exists), @(isDir)]);
142
-    
151
+
143
 }
152
 }
144
 
153
 
145
 RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
154
 RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
202
 RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback) {
211
 RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback) {
203
     NSError * error = nil;
212
     NSError * error = nil;
204
     NSString * tmpPath = nil;
213
     NSString * tmpPath = nil;
205
-    
214
+
206
     for(NSString * path in paths) {
215
     for(NSString * path in paths) {
207
         [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
216
         [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
208
         if(error != nil) {
217
         if(error != nil) {
211
         }
220
         }
212
     }
221
     }
213
     callback(@[[NSNull null]]);
222
     callback(@[[NSNull null]]);
214
-    
223
+
215
 }
224
 }
216
 
225
 
217
 RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
226
 RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
225
     }
234
     }
226
     NSError * error = nil;
235
     NSError * error = nil;
227
     NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
236
     NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
228
-    
237
+
229
     if(error == nil)
238
     if(error == nil)
230
         callback(@[[NSNull null], result == nil ? [NSNull null] :result ]);
239
         callback(@[[NSNull null], result == nil ? [NSNull null] :result ]);
231
     else
240
     else
232
         callback(@[[error localizedDescription], [NSNull null]]);
241
         callback(@[[error localizedDescription], [NSNull null]]);
233
-    
242
+
234
 }
243
 }
235
 
244
 
236
 RCT_EXPORT_METHOD(stat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
245
 RCT_EXPORT_METHOD(stat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
238
     BOOL exist = nil;
247
     BOOL exist = nil;
239
     BOOL isDir = nil;
248
     BOOL isDir = nil;
240
     NSError * error = nil;
249
     NSError * error = nil;
241
-    
250
+
242
     path = [RNFetchBlobFS getPathOfAsset:path];
251
     path = [RNFetchBlobFS getPathOfAsset:path];
243
-    
252
+
244
     exist = [fm fileExistsAtPath:path isDirectory:&isDir];
253
     exist = [fm fileExistsAtPath:path isDirectory:&isDir];
245
     if(exist == NO) {
254
     if(exist == NO) {
246
         callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
255
         callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
247
         return ;
256
         return ;
248
     }
257
     }
249
     NSData * res = [RNFetchBlobFS stat:path error:&error];
258
     NSData * res = [RNFetchBlobFS stat:path error:&error];
250
-    
259
+
251
     if(error == nil)
260
     if(error == nil)
252
         callback(@[[NSNull null], res]);
261
         callback(@[[NSNull null], res]);
253
     else
262
     else
254
         callback(@[[error localizedDescription], [NSNull null]]);
263
         callback(@[[error localizedDescription], [NSNull null]]);
255
-    
264
+
256
 }
265
 }
257
 
266
 
258
 RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
267
 RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
259
     NSFileManager* fm = [NSFileManager defaultManager];
268
     NSFileManager* fm = [NSFileManager defaultManager];
260
     BOOL exist = nil;
269
     BOOL exist = nil;
261
     BOOL isDir = nil;
270
     BOOL isDir = nil;
262
-    
271
+
263
     path = [RNFetchBlobFS getPathOfAsset:path];
272
     path = [RNFetchBlobFS getPathOfAsset:path];
264
-    
273
+
265
     exist = [fm fileExistsAtPath:path isDirectory:&isDir];
274
     exist = [fm fileExistsAtPath:path isDirectory:&isDir];
266
     if(exist == NO) {
275
     if(exist == NO) {
267
         callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
276
         callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
269
     }
278
     }
270
     NSError * error = nil;
279
     NSError * error = nil;
271
     NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
280
     NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
272
-    
281
+
273
     NSMutableArray * res = [[NSMutableArray alloc] init];
282
     NSMutableArray * res = [[NSMutableArray alloc] init];
274
     if(isDir == YES) {
283
     if(isDir == YES) {
275
         for(NSString * p in files) {
284
         for(NSString * p in files) {
280
     else {
289
     else {
281
         [res addObject:[RNFetchBlobFS stat:path error:&error]];
290
         [res addObject:[RNFetchBlobFS stat:path error:&error]];
282
     }
291
     }
283
-    
292
+
284
     if(error == nil)
293
     if(error == nil)
285
         callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
294
         callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
286
     else
295
     else
287
         callback(@[[error localizedDescription], [NSNull null]]);
296
         callback(@[[error localizedDescription], [NSNull null]]);
288
-    
297
+
289
 }
298
 }
290
 
299
 
291
 RCT_EXPORT_METHOD(cp:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
300
 RCT_EXPORT_METHOD(cp:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
292
     NSError * error = nil;
301
     NSError * error = nil;
293
     path = [RNFetchBlobFS getPathOfAsset:path];
302
     path = [RNFetchBlobFS getPathOfAsset:path];
294
     BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
303
     BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
295
-    
304
+
296
     if(error == nil)
305
     if(error == nil)
297
         callback(@[[NSNull null], @YES]);
306
         callback(@[[NSNull null], @YES]);
298
     else
307
     else
299
         callback(@[[error localizedDescription], @NO]);
308
         callback(@[[error localizedDescription], @NO]);
300
-    
309
+
301
 }
310
 }
302
 
311
 
303
 RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
312
 RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
304
     NSError * error = nil;
313
     NSError * error = nil;
305
     BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
314
     BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
306
-    
315
+
307
     if(error == nil)
316
     if(error == nil)
308
         callback(@[[NSNull null], @YES]);
317
         callback(@[[NSNull null], @YES]);
309
     else
318
     else
310
         callback(@[[error localizedDescription], @NO]);
319
         callback(@[[error localizedDescription], @NO]);
311
-    
320
+
312
 }
321
 }
313
 
322
 
314
 RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
323
 RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
322
 }
331
 }
323
 
332
 
324
 RCT_EXPORT_METHOD(readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
333
 RCT_EXPORT_METHOD(readFile:(NSString *)path encoding:(NSString *)encoding resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
325
-    
334
+
326
     [RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
335
     [RNFetchBlobFS readFile:path encoding:encoding resolver:resolve rejecter:reject onComplete:nil];
327
 })
336
 })
328
 
337
 
329
 RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding bufferSize:(int)bufferSize) {
338
 RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding bufferSize:(int)bufferSize) {
330
-    
339
+
331
     RNFetchBlobFS *fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
340
     RNFetchBlobFS *fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
332
     if(bufferSize == nil) {
341
     if(bufferSize == nil) {
333
         if([[encoding lowercaseString] isEqualToString:@"base64"])
342
         if([[encoding lowercaseString] isEqualToString:@"base64"])
340
 }
349
 }
341
 
350
 
342
 RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback) {
351
 RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback) {
343
-    
352
+
344
     callback(@[
353
     callback(@[
345
                [RNFetchBlobFS getDocumentDir],
354
                [RNFetchBlobFS getDocumentDir],
346
                [RNFetchBlobFS getCacheDir],
355
                [RNFetchBlobFS getCacheDir],
350
 RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
359
 RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
351
     [RNFetchBlobNetwork cancelRequest:taskId];
360
     [RNFetchBlobNetwork cancelRequest:taskId];
352
     callback(@[[NSNull null], taskId]);
361
     callback(@[[NSNull null], taskId]);
353
-    
362
+
354
 }
363
 }
355
 
364
 
356
 #pragma mark RNFetchBlob private methods
365
 #pragma mark RNFetchBlob private methods

+ 1
- 0
src/ios/RNFetchBlobConst.h View File

28
 extern NSString *const CONFIG_FILE_EXT;
28
 extern NSString *const CONFIG_FILE_EXT;
29
 extern NSString *const CONFIG_TRUSTY;
29
 extern NSString *const CONFIG_TRUSTY;
30
 extern NSString *const CONFIG_INDICATOR;
30
 extern NSString *const CONFIG_INDICATOR;
31
+extern NSString *const CONFIG_KEY;
31
 
32
 
32
 // fs events
33
 // fs events
33
 extern NSString *const FS_EVENT_DATA;
34
 extern NSString *const FS_EVENT_DATA;

+ 1
- 0
src/ios/RNFetchBlobConst.m View File

19
 extern NSString *const CONFIG_FILE_EXT = @"appendExt";
19
 extern NSString *const CONFIG_FILE_EXT = @"appendExt";
20
 extern NSString *const CONFIG_TRUSTY = @"trusty";
20
 extern NSString *const CONFIG_TRUSTY = @"trusty";
21
 extern NSString *const CONFIG_INDICATOR = @"indicator";
21
 extern NSString *const CONFIG_INDICATOR = @"indicator";
22
+extern NSString *const CONFIG_KEY = "@key";
22
 
23
 
23
 extern NSString *const EVENT_STATE_CHANGE = @"RNFetchBlobState";
24
 extern NSString *const EVENT_STATE_CHANGE = @"RNFetchBlobState";
24
 extern NSString *const MSG_EVENT = @"RNFetchBlobMessage";
25
 extern NSString *const MSG_EVENT = @"RNFetchBlobMessage";

+ 43
- 14
src/ios/RNFetchBlobNetwork.m View File

14
 #import "RNFetchBlobFS.h"
14
 #import "RNFetchBlobFS.h"
15
 #import "RNFetchBlobNetwork.h"
15
 #import "RNFetchBlobNetwork.h"
16
 #import "RNFetchBlobConst.h"
16
 #import "RNFetchBlobConst.h"
17
+#import <CommonCrypto/CommonDigest.h>
17
 
18
 
18
 ////////////////////////////////////////
19
 ////////////////////////////////////////
19
 //
20
 //
64
 
65
 
65
 // removing case from headers
66
 // removing case from headers
66
 + (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers {
67
 + (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers {
67
-    
68
+
68
     NSMutableDictionary * mheaders = [[NSMutableDictionary alloc]init];
69
     NSMutableDictionary * mheaders = [[NSMutableDictionary alloc]init];
69
     for(NSString * key in headers) {
70
     for(NSString * key in headers) {
70
         [mheaders setValue:[headers valueForKey:key] forKey:[key lowercaseString]];
71
         [mheaders setValue:[headers valueForKey:key] forKey:[key lowercaseString]];
71
     }
72
     }
72
-    
73
+
73
     return mheaders;
74
     return mheaders;
74
 }
75
 }
75
 
76
 
77
+- (NSString *)md5 {
78
+    const char* str = [self UTF8String];
79
+    unsigned char result[CC_MD5_DIGEST_LENGTH];
80
+    CC_MD5(str, (CC_LONG)strlen(str), result);
81
+
82
+    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
83
+    for(int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
84
+        [ret appendFormat:@"%02x",result[i]];
85
+    }
86
+    return ret;
87
+}
88
+
76
 // send HTTP request
89
 // send HTTP request
77
 - (void) sendRequest:(NSDictionary  * _Nullable )options
90
 - (void) sendRequest:(NSDictionary  * _Nullable )options
78
        contentLength:(long) contentLength
91
        contentLength:(long) contentLength
88
     self.expectedBytes = 0;
101
     self.expectedBytes = 0;
89
     self.receivedBytes = 0;
102
     self.receivedBytes = 0;
90
     self.options = options;
103
     self.options = options;
91
-    
104
+
92
     NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
105
     NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
93
     NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
106
     NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
107
+	NSString * key = [self.options valueForKey:CONFIG_KEY];
94
     NSURLSession * session;
108
     NSURLSession * session;
95
-    
109
+
96
     bodyLength = contentLength;
110
     bodyLength = contentLength;
97
-    
111
+
98
     // the session trust any SSL certification
112
     // the session trust any SSL certification
99
 
113
 
100
     NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
114
     NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
101
     session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:[NSOperationQueue mainQueue]];
115
     session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:[NSOperationQueue mainQueue]];
102
-    
116
+
103
     if(path != nil || [self.options valueForKey:CONFIG_USE_TEMP]!= nil)
117
     if(path != nil || [self.options valueForKey:CONFIG_USE_TEMP]!= nil)
104
     {
118
     {
105
         respFile = YES;
119
         respFile = YES;
120
+
121
+		NSString* cacheKey = taskId;
122
+		if (key != nil) {
123
+			cacheKey = [key md5];
124
+			if (cacheKey == nil) {
125
+				cacheKey = taskId;
126
+			}
127
+
128
+			destPath = [RNFetchBlobFS getTempPath:cacheKey withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
129
+            if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
130
+				callback([NSNull null], destPath]);
131
+                return;
132
+            }
133
+		}
134
+
106
         if(path != nil)
135
         if(path != nil)
107
             destPath = path;
136
             destPath = path;
108
-        else
109
-            destPath = [RNFetchBlobFS getTempPath:taskId withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
137
+        // else
138
+        //     destPath = [RNFetchBlobFS getTempPath:cacheKey withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
110
     }
139
     }
111
     else
140
     else
112
     {
141
     {
116
     NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
145
     NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
117
     [taskTable setValue:task forKey:taskId];
146
     [taskTable setValue:task forKey:taskId];
118
     [task resume];
147
     [task resume];
119
-    
148
+
120
     // network status indicator
149
     // network status indicator
121
     if([[options objectForKey:CONFIG_INDICATOR] boolValue] == YES)
150
     if([[options objectForKey:CONFIG_INDICATOR] boolValue] == YES)
122
         [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
151
         [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
170
             }
199
             }
171
          ];
200
          ];
172
     }
201
     }
173
-    
202
+
174
     if(respFile == YES)
203
     if(respFile == YES)
175
     {
204
     {
176
         NSFileManager * fm = [NSFileManager defaultManager];
205
         NSFileManager * fm = [NSFileManager defaultManager];
198
     {
227
     {
199
         [writeStream write:[data bytes] maxLength:[data length]];
228
         [writeStream write:[data bytes] maxLength:[data length]];
200
     }
229
     }
201
-    
230
+
202
     [self.bridge.eventDispatcher
231
     [self.bridge.eventDispatcher
203
      sendDeviceEventWithName:@"RNFetchBlobProgress"
232
      sendDeviceEventWithName:@"RNFetchBlobProgress"
204
      body:@{
233
      body:@{
207
             @"total": [NSString stringWithFormat:@"%d", expectedBytes]
236
             @"total": [NSString stringWithFormat:@"%d", expectedBytes]
208
             }
237
             }
209
      ];
238
      ];
210
-    
239
+
211
 }
240
 }
212
 
241
 
213
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
242
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
247
 }
276
 }
248
 
277
 
249
 //- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
278
 //- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
250
-//    
279
+//
251
 //}
280
 //}
252
 
281
 
253
 //- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
282
 //- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
293
     }
322
     }
294
 }
323
 }
295
 
324
 
296
-@end
325
+@end

+ 9
- 0
src/ios/RNFetchBlobReqBuilder.h View File

29
                      body:(NSString *)body
29
                      body:(NSString *)body
30
                onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete;
30
                onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete;
31
 
31
 
32
++(void) buildEncodedRequest:(NSDictionary *)options
33
+                      taskId:(NSString *)taskId
34
+                      method:(NSString *)method
35
+                         url:(NSString *)url
36
+                     headers:(NSDictionary *)headers
37
+                        form:(NSString *)body
38
+                  onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete;
39
+
40
+
32
 @end
41
 @end
33
 
42
 
34
 #endif /* RNFetchBlobReqBuilder_h */
43
 #endif /* RNFetchBlobReqBuilder_h */

+ 22
- 8
src/ios/RNFetchBlobReqBuilder.m View File

14
 
14
 
15
 @interface RNFetchBlobReqBuilder()
15
 @interface RNFetchBlobReqBuilder()
16
 {
16
 {
17
-    
17
+
18
 }
18
 }
19
 @end
19
 @end
20
 
20
 
36
     NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
36
     NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
37
     NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
37
     NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
38
     NSNumber * timeStampObj = [NSNumber numberWithDouble: timeStamp];
38
     NSNumber * timeStampObj = [NSNumber numberWithDouble: timeStamp];
39
-    
39
+
40
     // generate boundary
40
     // generate boundary
41
     NSString * boundary = [NSString stringWithFormat:@"RNFetchBlob%d", timeStampObj];
41
     NSString * boundary = [NSString stringWithFormat:@"RNFetchBlob%d", timeStampObj];
42
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
42
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
58
             [request setAllHTTPHeaderFields:mheaders];
58
             [request setAllHTTPHeaderFields:mheaders];
59
             onComplete(request, [formData length]);
59
             onComplete(request, [formData length]);
60
         }];
60
         }];
61
-        
61
+
62
     });
62
     });
63
 }
63
 }
64
 
64
 
76
     NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
76
     NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
77
                                     initWithURL:[NSURL
77
                                     initWithURL:[NSURL
78
                                                  URLWithString: encodedUrl]];
78
                                                  URLWithString: encodedUrl]];
79
-    
79
+
80
     NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
80
     NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
81
     // move heavy task to another thread
81
     // move heavy task to another thread
82
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
82
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
86
         if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
86
         if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
87
             // generate octet-stream body
87
             // generate octet-stream body
88
             if(body != nil) {
88
             if(body != nil) {
89
-                
89
+
90
                 // when body is a string contains file path prefix, try load file from the path
90
                 // when body is a string contains file path prefix, try load file from the path
91
                 if([body hasPrefix:FILE_PREFIX]) {
91
                 if([body hasPrefix:FILE_PREFIX]) {
92
                     NSString * orgPath = [body substringFromIndex:[FILE_PREFIX length]];
92
                     NSString * orgPath = [body substringFromIndex:[FILE_PREFIX length]];
130
                 
130
                 
131
             }
131
             }
132
         }
132
         }
133
-        
133
+
134
         [request setHTTPMethod: method];
134
         [request setHTTPMethod: method];
135
         [request setAllHTTPHeaderFields:mheaders];
135
         [request setAllHTTPHeaderFields:mheaders];
136
-        
136
+
137
         onComplete(request, size);
137
         onComplete(request, size);
138
     });
138
     });
139
 }
139
 }
140
 
140
 
141
++(void) buildEncodedRequest:(NSDictionary *)options
142
+                   taskId:(NSString *)taskId
143
+                   method:(NSString *)method
144
+                      url:(NSString *)url
145
+                  headers:(NSDictionary *)headers
146
+                     body:(NSString *)body
147
+               onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete
148
+{
149
+	NSMutableData * formData = [[NSMutableData alloc] init];
150
+	[formData appendData:[[NSString stringWithFormat:@"%@", body] dataUsingEncoding:NSUTF8StringEncoding]];
151
+	onComplete(formData);
152
+}
153
+
154
+
141
 +(void) buildFormBody:(NSArray *)form boundary:(NSString *)boundary onComplete:(void(^)(NSData * formData))onComplete
155
 +(void) buildFormBody:(NSArray *)form boundary:(NSString *)boundary onComplete:(void(^)(NSData * formData))onComplete
142
 {
156
 {
143
     NSMutableData * formData = [[NSMutableData alloc] init];
157
     NSMutableData * formData = [[NSMutableData alloc] init];
204
             }
218
             }
205
             else
219
             else
206
                 onComplete(formData);
220
                 onComplete(formData);
207
-            
221
+
208
         };
222
         };
209
         getFieldData([form objectAtIndex:i]);
223
         getFieldData([form objectAtIndex:i]);
210
     }
224
     }