|
@@ -56,7 +56,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
56
|
56
|
const char* str = [input UTF8String];
|
57
|
57
|
unsigned char result[CC_MD5_DIGEST_LENGTH];
|
58
|
58
|
CC_MD5(str, (CC_LONG)strlen(str), result);
|
59
|
|
-
|
|
59
|
+
|
60
|
60
|
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
|
61
|
61
|
for (int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
|
62
|
62
|
[ret appendFormat:@"%02x",result[i]];
|
|
@@ -80,20 +80,20 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
80
|
80
|
self.expectedBytes = 0;
|
81
|
81
|
self.receivedBytes = 0;
|
82
|
82
|
self.options = options;
|
83
|
|
-
|
|
83
|
+
|
84
|
84
|
backgroundTask = [[options valueForKey:@"IOSBackgroundTask"] boolValue];
|
85
|
85
|
// when followRedirect not set in options, defaults to TRUE
|
86
|
86
|
followRedirect = [options valueForKey:@"followRedirect"] == nil ? YES : [[options valueForKey:@"followRedirect"] boolValue];
|
87
|
87
|
isIncrement = [[options valueForKey:@"increment"] boolValue];
|
88
|
88
|
redirects = [[NSMutableArray alloc] init];
|
89
|
|
-
|
|
89
|
+
|
90
|
90
|
if (req.URL) {
|
91
|
91
|
[redirects addObject:req.URL.absoluteString];
|
92
|
92
|
}
|
93
|
|
-
|
|
93
|
+
|
94
|
94
|
// set response format
|
95
|
95
|
NSString * rnfbResp = [req.allHTTPHeaderFields valueForKey:@"RNFB-Response"];
|
96
|
|
-
|
|
96
|
+
|
97
|
97
|
if ([[rnfbResp lowercaseString] isEqualToString:@"base64"]) {
|
98
|
98
|
responseFormat = BASE64;
|
99
|
99
|
} else if ([[rnfbResp lowercaseString] isEqualToString:@"utf8"]) {
|
|
@@ -101,52 +101,56 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
101
|
101
|
} else {
|
102
|
102
|
responseFormat = AUTO;
|
103
|
103
|
}
|
104
|
|
-
|
|
104
|
+
|
105
|
105
|
NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
|
106
|
106
|
NSString * key = [self.options valueForKey:CONFIG_KEY];
|
107
|
107
|
NSURLSession * session;
|
108
|
|
-
|
|
108
|
+
|
109
|
109
|
bodyLength = contentLength;
|
110
|
|
-
|
|
110
|
+
|
111
|
111
|
// the session trust any SSL certification
|
112
|
112
|
NSURLSessionConfiguration *defaultConfigObject;
|
113
|
|
-
|
|
113
|
+
|
114
|
114
|
defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
|
115
|
|
-
|
|
115
|
+
|
116
|
116
|
if (backgroundTask) {
|
117
|
117
|
defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:taskId];
|
118
|
118
|
}
|
119
|
|
-
|
|
119
|
+
|
120
|
120
|
// request timeout, -1 if not set in options
|
121
|
121
|
float timeout = [options valueForKey:@"timeout"] == nil ? -1 : [[options valueForKey:@"timeout"] floatValue];
|
122
|
|
-
|
|
122
|
+
|
123
|
123
|
if (timeout > 0) {
|
124
|
124
|
defaultConfigObject.timeoutIntervalForRequest = timeout/1000;
|
125
|
125
|
}
|
126
|
|
-
|
|
126
|
+
|
|
127
|
+ if([options valueForKey:CONFIG_WIFI_ONLY] != nil && ![options[CONFIG_WIFI_ONLY] boolValue]){
|
|
128
|
+ [defaultConfigObject setAllowsCellularAccess:NO];
|
|
129
|
+ }
|
|
130
|
+
|
127
|
131
|
defaultConfigObject.HTTPMaximumConnectionsPerHost = 10;
|
128
|
132
|
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:operationQueue];
|
129
|
|
-
|
|
133
|
+
|
130
|
134
|
if (path || [self.options valueForKey:CONFIG_USE_TEMP]) {
|
131
|
135
|
respFile = YES;
|
132
|
|
-
|
|
136
|
+
|
133
|
137
|
NSString* cacheKey = taskId;
|
134
|
138
|
if (key) {
|
135
|
139
|
cacheKey = [self md5:key];
|
136
|
|
-
|
|
140
|
+
|
137
|
141
|
if (!cacheKey) {
|
138
|
142
|
cacheKey = taskId;
|
139
|
143
|
}
|
140
|
|
-
|
|
144
|
+
|
141
|
145
|
destPath = [RNFetchBlobFS getTempPath:cacheKey withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
|
142
|
|
-
|
|
146
|
+
|
143
|
147
|
if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
|
144
|
148
|
callback(@[[NSNull null], RESP_TYPE_PATH, destPath]);
|
145
|
|
-
|
|
149
|
+
|
146
|
150
|
return;
|
147
|
151
|
}
|
148
|
152
|
}
|
149
|
|
-
|
|
153
|
+
|
150
|
154
|
if (path) {
|
151
|
155
|
destPath = path;
|
152
|
156
|
} else {
|
|
@@ -156,10 +160,10 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
156
|
160
|
respData = [[NSMutableData alloc] init];
|
157
|
161
|
respFile = NO;
|
158
|
162
|
}
|
159
|
|
-
|
|
163
|
+
|
160
|
164
|
self.task = [session dataTaskWithRequest:req];
|
161
|
165
|
[self.task resume];
|
162
|
|
-
|
|
166
|
+
|
163
|
167
|
// network status indicator
|
164
|
168
|
if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
|
165
|
169
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -183,17 +187,17 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
183
|
187
|
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
|
184
|
188
|
{
|
185
|
189
|
expectedBytes = [response expectedContentLength];
|
186
|
|
-
|
|
190
|
+
|
187
|
191
|
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
|
188
|
192
|
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
189
|
193
|
NSString * respType = @"";
|
190
|
194
|
respStatus = statusCode;
|
191
|
|
-
|
|
195
|
+
|
192
|
196
|
if ([response respondsToSelector:@selector(allHeaderFields)])
|
193
|
197
|
{
|
194
|
198
|
NSDictionary *headers = [httpResponse allHeaderFields];
|
195
|
199
|
NSString * respCType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"Content-Type" fromHeaders:headers] lowercaseString];
|
196
|
|
-
|
|
200
|
+
|
197
|
201
|
if (self.isServerPush) {
|
198
|
202
|
if (partBuffer) {
|
199
|
203
|
[self.bridge.eventDispatcher
|
|
@@ -204,7 +208,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
204
|
208
|
}
|
205
|
209
|
];
|
206
|
210
|
}
|
207
|
|
-
|
|
211
|
+
|
208
|
212
|
partBuffer = [[NSMutableData alloc] init];
|
209
|
213
|
completionHandler(NSURLSessionResponseAllow);
|
210
|
214
|
|
|
@@ -212,11 +216,11 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
212
|
216
|
} else {
|
213
|
217
|
self.isServerPush = [[respCType lowercaseString] RNFBContainsString:@"multipart/x-mixed-replace;"];
|
214
|
218
|
}
|
215
|
|
-
|
|
219
|
+
|
216
|
220
|
if(respCType)
|
217
|
221
|
{
|
218
|
222
|
NSArray * extraBlobCTypes = [options objectForKey:CONFIG_EXTRA_BLOB_CTYPE];
|
219
|
|
-
|
|
223
|
+
|
220
|
224
|
if ([respCType RNFBContainsString:@"text/"]) {
|
221
|
225
|
respType = @"text";
|
222
|
226
|
} else if ([respCType RNFBContainsString:@"application/json"]) {
|
|
@@ -232,7 +236,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
232
|
236
|
}
|
233
|
237
|
} else {
|
234
|
238
|
respType = @"blob";
|
235
|
|
-
|
|
239
|
+
|
236
|
240
|
// for XMLHttpRequest, switch response data handling strategy automatically
|
237
|
241
|
if ([options valueForKey:@"auto"]) {
|
238
|
242
|
respFile = YES;
|
|
@@ -242,7 +246,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
242
|
246
|
} else {
|
243
|
247
|
respType = @"text";
|
244
|
248
|
}
|
245
|
|
-
|
|
249
|
+
|
246
|
250
|
#pragma mark - handling cookies
|
247
|
251
|
// # 153 get cookies
|
248
|
252
|
if (response.URL) {
|
|
@@ -252,7 +256,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
252
|
256
|
[cookieStore setCookies:cookies forURL:response.URL mainDocumentURL:nil];
|
253
|
257
|
}
|
254
|
258
|
}
|
255
|
|
-
|
|
259
|
+
|
256
|
260
|
[self.bridge.eventDispatcher
|
257
|
261
|
sendDeviceEventWithName: EVENT_STATE_CHANGE
|
258
|
262
|
body:@{
|
|
@@ -268,33 +272,33 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
268
|
272
|
} else {
|
269
|
273
|
NSLog(@"oops");
|
270
|
274
|
}
|
271
|
|
-
|
|
275
|
+
|
272
|
276
|
if (respFile)
|
273
|
277
|
{
|
274
|
278
|
@try{
|
275
|
279
|
NSFileManager * fm = [NSFileManager defaultManager];
|
276
|
280
|
NSString * folder = [destPath stringByDeletingLastPathComponent];
|
277
|
|
-
|
|
281
|
+
|
278
|
282
|
if (![fm fileExistsAtPath:folder]) {
|
279
|
283
|
[fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil];
|
280
|
284
|
}
|
281
|
|
-
|
|
285
|
+
|
282
|
286
|
// if not set overwrite in options, defaults to TRUE
|
283
|
287
|
BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue];
|
284
|
288
|
BOOL appendToExistingFile = [destPath RNFBContainsString:@"?append=true"];
|
285
|
|
-
|
|
289
|
+
|
286
|
290
|
appendToExistingFile = !overwrite;
|
287
|
|
-
|
|
291
|
+
|
288
|
292
|
// For solving #141 append response data if the file already exists
|
289
|
293
|
// base on PR#139 @kejinliang
|
290
|
294
|
if (appendToExistingFile) {
|
291
|
295
|
destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""];
|
292
|
296
|
}
|
293
|
|
-
|
|
297
|
+
|
294
|
298
|
if (![fm fileExistsAtPath:destPath]) {
|
295
|
299
|
[fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil];
|
296
|
300
|
}
|
297
|
|
-
|
|
301
|
+
|
298
|
302
|
writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile];
|
299
|
303
|
[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
300
|
304
|
[writeStream open];
|
|
@@ -304,7 +308,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
304
|
308
|
NSLog(@"write file error");
|
305
|
309
|
}
|
306
|
310
|
}
|
307
|
|
-
|
|
311
|
+
|
308
|
312
|
completionHandler(NSURLSessionResponseAllow);
|
309
|
313
|
}
|
310
|
314
|
|
|
@@ -316,30 +320,30 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
316
|
320
|
if (self.isServerPush)
|
317
|
321
|
{
|
318
|
322
|
[partBuffer appendData:data];
|
319
|
|
-
|
|
323
|
+
|
320
|
324
|
return ;
|
321
|
325
|
}
|
322
|
|
-
|
|
326
|
+
|
323
|
327
|
NSNumber * received = [NSNumber numberWithLong:[data length]];
|
324
|
328
|
receivedBytes += [received longValue];
|
325
|
329
|
NSString * chunkString = @"";
|
326
|
|
-
|
|
330
|
+
|
327
|
331
|
if (isIncrement) {
|
328
|
332
|
chunkString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
329
|
333
|
}
|
330
|
|
-
|
|
334
|
+
|
331
|
335
|
if (respFile) {
|
332
|
336
|
[writeStream write:[data bytes] maxLength:[data length]];
|
333
|
337
|
} else {
|
334
|
338
|
[respData appendData:data];
|
335
|
339
|
}
|
336
|
|
-
|
|
340
|
+
|
337
|
341
|
if (expectedBytes == 0) {
|
338
|
342
|
return;
|
339
|
343
|
}
|
340
|
|
-
|
|
344
|
+
|
341
|
345
|
NSNumber * now =[NSNumber numberWithFloat:((float)receivedBytes/(float)expectedBytes)];
|
342
|
|
-
|
|
346
|
+
|
343
|
347
|
if ([self.progressConfig shouldReport:now]) {
|
344
|
348
|
[self.bridge.eventDispatcher
|
345
|
349
|
sendDeviceEventWithName:EVENT_PROGRESS
|
|
@@ -363,16 +367,19 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
363
|
367
|
|
364
|
368
|
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
365
|
369
|
{
|
366
|
|
-
|
|
370
|
+
|
367
|
371
|
self.error = error;
|
368
|
372
|
NSString * errMsg;
|
369
|
373
|
NSString * respStr;
|
370
|
374
|
NSString * rnfbRespType;
|
371
|
|
-
|
372
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
373
|
|
- [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
|
374
|
|
- });
|
375
|
|
-
|
|
375
|
+
|
|
376
|
+ // only run this if we were requested to change it
|
|
377
|
+ if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
|
|
378
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
379
|
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
|
|
380
|
+ });
|
|
381
|
+ }
|
|
382
|
+
|
376
|
383
|
if (error) {
|
377
|
384
|
if (error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled) {
|
378
|
385
|
errMsg = @"task cancelled";
|
|
@@ -380,7 +387,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
380
|
387
|
errMsg = [error localizedDescription];
|
381
|
388
|
}
|
382
|
389
|
}
|
383
|
|
-
|
|
390
|
+
|
384
|
391
|
if (respFile) {
|
385
|
392
|
[writeStream close];
|
386
|
393
|
rnfbRespType = RESP_TYPE_PATH;
|
|
@@ -391,7 +398,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
391
|
398
|
// if it turns out not to be `nil` that means the response data contains valid UTF8 string,
|
392
|
399
|
// in order to properly encode the UTF8 string, use URL encoding before BASE64 encoding.
|
393
|
400
|
NSString * utf8 = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
|
394
|
|
-
|
|
401
|
+
|
395
|
402
|
if (responseFormat == BASE64) {
|
396
|
403
|
rnfbRespType = RESP_TYPE_BASE64;
|
397
|
404
|
respStr = [respData base64EncodedStringWithOptions:0];
|
|
@@ -408,18 +415,18 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
408
|
415
|
}
|
409
|
416
|
}
|
410
|
417
|
}
|
411
|
|
-
|
412
|
|
-
|
|
418
|
+
|
|
419
|
+
|
413
|
420
|
callback(@[
|
414
|
421
|
errMsg ?: [NSNull null],
|
415
|
422
|
rnfbRespType ?: @"",
|
416
|
423
|
respStr ?: [NSNull null]
|
417
|
424
|
]);
|
418
|
|
-
|
|
425
|
+
|
419
|
426
|
respData = nil;
|
420
|
427
|
receivedBytes = 0;
|
421
|
428
|
[session finishTasksAndInvalidate];
|
422
|
|
-
|
|
429
|
+
|
423
|
430
|
}
|
424
|
431
|
|
425
|
432
|
// upload progress handler
|
|
@@ -428,7 +435,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
428
|
435
|
if (totalBytesExpectedToWrite == 0) {
|
429
|
436
|
return;
|
430
|
437
|
}
|
431
|
|
-
|
|
438
|
+
|
432
|
439
|
NSNumber * now = [NSNumber numberWithFloat:((float)totalBytesWritten/(float)totalBytesExpectedToWrite)];
|
433
|
440
|
|
434
|
441
|
if ([self.uploadProgressConfig shouldReport:now]) {
|
|
@@ -461,12 +468,12 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
461
|
468
|
|
462
|
469
|
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
|
463
|
470
|
{
|
464
|
|
-
|
|
471
|
+
|
465
|
472
|
if (followRedirect) {
|
466
|
473
|
if (request.URL) {
|
467
|
474
|
[redirects addObject:[request.URL absoluteString]];
|
468
|
475
|
}
|
469
|
|
-
|
|
476
|
+
|
470
|
477
|
completionHandler(request);
|
471
|
478
|
} else {
|
472
|
479
|
completionHandler(nil);
|