|
@@ -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,56 +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
|
127
|
if([options valueForKey:CONFIG_WIFI_ONLY] != nil && ![options[CONFIG_WIFI_ONLY] boolValue]){
|
128
|
128
|
[defaultConfigObject setAllowsCellularAccess:NO];
|
129
|
129
|
}
|
130
|
|
-
|
|
130
|
+
|
131
|
131
|
defaultConfigObject.HTTPMaximumConnectionsPerHost = 10;
|
132
|
132
|
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:operationQueue];
|
133
|
|
-
|
|
133
|
+
|
134
|
134
|
if (path || [self.options valueForKey:CONFIG_USE_TEMP]) {
|
135
|
135
|
respFile = YES;
|
136
|
|
-
|
|
136
|
+
|
137
|
137
|
NSString* cacheKey = taskId;
|
138
|
138
|
if (key) {
|
139
|
139
|
cacheKey = [self md5:key];
|
140
|
|
-
|
|
140
|
+
|
141
|
141
|
if (!cacheKey) {
|
142
|
142
|
cacheKey = taskId;
|
143
|
143
|
}
|
144
|
|
-
|
|
144
|
+
|
145
|
145
|
destPath = [RNFetchBlobFS getTempPath:cacheKey withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
|
146
|
|
-
|
|
146
|
+
|
147
|
147
|
if ([[NSFileManager defaultManager] fileExistsAtPath:destPath]) {
|
148
|
148
|
callback(@[[NSNull null], RESP_TYPE_PATH, destPath]);
|
149
|
|
-
|
|
149
|
+
|
150
|
150
|
return;
|
151
|
151
|
}
|
152
|
152
|
}
|
153
|
|
-
|
|
153
|
+
|
154
|
154
|
if (path) {
|
155
|
155
|
destPath = path;
|
156
|
156
|
} else {
|
|
@@ -160,10 +160,10 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
160
|
160
|
respData = [[NSMutableData alloc] init];
|
161
|
161
|
respFile = NO;
|
162
|
162
|
}
|
163
|
|
-
|
|
163
|
+
|
164
|
164
|
self.task = [session dataTaskWithRequest:req];
|
165
|
165
|
[self.task resume];
|
166
|
|
-
|
|
166
|
+
|
167
|
167
|
// network status indicator
|
168
|
168
|
if ([[options objectForKey:CONFIG_INDICATOR] boolValue]) {
|
169
|
169
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -187,17 +187,17 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
187
|
187
|
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
|
188
|
188
|
{
|
189
|
189
|
expectedBytes = [response expectedContentLength];
|
190
|
|
-
|
|
190
|
+
|
191
|
191
|
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
|
192
|
192
|
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
193
|
193
|
NSString * respType = @"";
|
194
|
194
|
respStatus = statusCode;
|
195
|
|
-
|
|
195
|
+
|
196
|
196
|
if ([response respondsToSelector:@selector(allHeaderFields)])
|
197
|
197
|
{
|
198
|
198
|
NSDictionary *headers = [httpResponse allHeaderFields];
|
199
|
199
|
NSString * respCType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"Content-Type" fromHeaders:headers] lowercaseString];
|
200
|
|
-
|
|
200
|
+
|
201
|
201
|
if (self.isServerPush) {
|
202
|
202
|
if (partBuffer) {
|
203
|
203
|
[self.bridge.eventDispatcher
|
|
@@ -208,7 +208,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
208
|
208
|
}
|
209
|
209
|
];
|
210
|
210
|
}
|
211
|
|
-
|
|
211
|
+
|
212
|
212
|
partBuffer = [[NSMutableData alloc] init];
|
213
|
213
|
completionHandler(NSURLSessionResponseAllow);
|
214
|
214
|
|
|
@@ -216,11 +216,11 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
216
|
216
|
} else {
|
217
|
217
|
self.isServerPush = [[respCType lowercaseString] RNFBContainsString:@"multipart/x-mixed-replace;"];
|
218
|
218
|
}
|
219
|
|
-
|
|
219
|
+
|
220
|
220
|
if(respCType)
|
221
|
221
|
{
|
222
|
222
|
NSArray * extraBlobCTypes = [options objectForKey:CONFIG_EXTRA_BLOB_CTYPE];
|
223
|
|
-
|
|
223
|
+
|
224
|
224
|
if ([respCType RNFBContainsString:@"text/"]) {
|
225
|
225
|
respType = @"text";
|
226
|
226
|
} else if ([respCType RNFBContainsString:@"application/json"]) {
|
|
@@ -236,7 +236,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
236
|
236
|
}
|
237
|
237
|
} else {
|
238
|
238
|
respType = @"blob";
|
239
|
|
-
|
|
239
|
+
|
240
|
240
|
// for XMLHttpRequest, switch response data handling strategy automatically
|
241
|
241
|
if ([options valueForKey:@"auto"]) {
|
242
|
242
|
respFile = YES;
|
|
@@ -246,7 +246,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
246
|
246
|
} else {
|
247
|
247
|
respType = @"text";
|
248
|
248
|
}
|
249
|
|
-
|
|
249
|
+
|
250
|
250
|
#pragma mark - handling cookies
|
251
|
251
|
// # 153 get cookies
|
252
|
252
|
if (response.URL) {
|
|
@@ -256,7 +256,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
256
|
256
|
[cookieStore setCookies:cookies forURL:response.URL mainDocumentURL:nil];
|
257
|
257
|
}
|
258
|
258
|
}
|
259
|
|
-
|
|
259
|
+
|
260
|
260
|
[self.bridge.eventDispatcher
|
261
|
261
|
sendDeviceEventWithName: EVENT_STATE_CHANGE
|
262
|
262
|
body:@{
|
|
@@ -272,33 +272,33 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
272
|
272
|
} else {
|
273
|
273
|
NSLog(@"oops");
|
274
|
274
|
}
|
275
|
|
-
|
|
275
|
+
|
276
|
276
|
if (respFile)
|
277
|
277
|
{
|
278
|
278
|
@try{
|
279
|
279
|
NSFileManager * fm = [NSFileManager defaultManager];
|
280
|
280
|
NSString * folder = [destPath stringByDeletingLastPathComponent];
|
281
|
|
-
|
|
281
|
+
|
282
|
282
|
if (![fm fileExistsAtPath:folder]) {
|
283
|
283
|
[fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:nil];
|
284
|
284
|
}
|
285
|
|
-
|
|
285
|
+
|
286
|
286
|
// if not set overwrite in options, defaults to TRUE
|
287
|
287
|
BOOL overwrite = [options valueForKey:@"overwrite"] == nil ? YES : [[options valueForKey:@"overwrite"] boolValue];
|
288
|
288
|
BOOL appendToExistingFile = [destPath RNFBContainsString:@"?append=true"];
|
289
|
|
-
|
|
289
|
+
|
290
|
290
|
appendToExistingFile = !overwrite;
|
291
|
|
-
|
|
291
|
+
|
292
|
292
|
// For solving #141 append response data if the file already exists
|
293
|
293
|
// base on PR#139 @kejinliang
|
294
|
294
|
if (appendToExistingFile) {
|
295
|
295
|
destPath = [destPath stringByReplacingOccurrencesOfString:@"?append=true" withString:@""];
|
296
|
296
|
}
|
297
|
|
-
|
|
297
|
+
|
298
|
298
|
if (![fm fileExistsAtPath:destPath]) {
|
299
|
299
|
[fm createFileAtPath:destPath contents:[[NSData alloc] init] attributes:nil];
|
300
|
300
|
}
|
301
|
|
-
|
|
301
|
+
|
302
|
302
|
writeStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:appendToExistingFile];
|
303
|
303
|
[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
|
304
|
304
|
[writeStream open];
|
|
@@ -308,7 +308,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
308
|
308
|
NSLog(@"write file error");
|
309
|
309
|
}
|
310
|
310
|
}
|
311
|
|
-
|
|
311
|
+
|
312
|
312
|
completionHandler(NSURLSessionResponseAllow);
|
313
|
313
|
}
|
314
|
314
|
|
|
@@ -320,30 +320,30 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
320
|
320
|
if (self.isServerPush)
|
321
|
321
|
{
|
322
|
322
|
[partBuffer appendData:data];
|
323
|
|
-
|
|
323
|
+
|
324
|
324
|
return ;
|
325
|
325
|
}
|
326
|
|
-
|
|
326
|
+
|
327
|
327
|
NSNumber * received = [NSNumber numberWithLong:[data length]];
|
328
|
328
|
receivedBytes += [received longValue];
|
329
|
329
|
NSString * chunkString = @"";
|
330
|
|
-
|
|
330
|
+
|
331
|
331
|
if (isIncrement) {
|
332
|
332
|
chunkString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
333
|
333
|
}
|
334
|
|
-
|
|
334
|
+
|
335
|
335
|
if (respFile) {
|
336
|
336
|
[writeStream write:[data bytes] maxLength:[data length]];
|
337
|
337
|
} else {
|
338
|
338
|
[respData appendData:data];
|
339
|
339
|
}
|
340
|
|
-
|
|
340
|
+
|
341
|
341
|
if (expectedBytes == 0) {
|
342
|
342
|
return;
|
343
|
343
|
}
|
344
|
|
-
|
|
344
|
+
|
345
|
345
|
NSNumber * now =[NSNumber numberWithFloat:((float)receivedBytes/(float)expectedBytes)];
|
346
|
|
-
|
|
346
|
+
|
347
|
347
|
if ([self.progressConfig shouldReport:now]) {
|
348
|
348
|
[self.bridge.eventDispatcher
|
349
|
349
|
sendDeviceEventWithName:EVENT_PROGRESS
|
|
@@ -367,16 +367,19 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
367
|
367
|
|
368
|
368
|
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
369
|
369
|
{
|
370
|
|
-
|
|
370
|
+
|
371
|
371
|
self.error = error;
|
372
|
372
|
NSString * errMsg;
|
373
|
373
|
NSString * respStr;
|
374
|
374
|
NSString * rnfbRespType;
|
375
|
|
-
|
376
|
|
- dispatch_async(dispatch_get_main_queue(), ^{
|
377
|
|
- [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
|
378
|
|
- });
|
379
|
|
-
|
|
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
|
+
|
380
|
383
|
if (error) {
|
381
|
384
|
if (error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled) {
|
382
|
385
|
errMsg = @"task cancelled";
|
|
@@ -384,7 +387,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
384
|
387
|
errMsg = [error localizedDescription];
|
385
|
388
|
}
|
386
|
389
|
}
|
387
|
|
-
|
|
390
|
+
|
388
|
391
|
if (respFile) {
|
389
|
392
|
[writeStream close];
|
390
|
393
|
rnfbRespType = RESP_TYPE_PATH;
|
|
@@ -395,7 +398,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
395
|
398
|
// if it turns out not to be `nil` that means the response data contains valid UTF8 string,
|
396
|
399
|
// in order to properly encode the UTF8 string, use URL encoding before BASE64 encoding.
|
397
|
400
|
NSString * utf8 = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
|
398
|
|
-
|
|
401
|
+
|
399
|
402
|
if (responseFormat == BASE64) {
|
400
|
403
|
rnfbRespType = RESP_TYPE_BASE64;
|
401
|
404
|
respStr = [respData base64EncodedStringWithOptions:0];
|
|
@@ -412,18 +415,18 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
412
|
415
|
}
|
413
|
416
|
}
|
414
|
417
|
}
|
415
|
|
-
|
416
|
|
-
|
|
418
|
+
|
|
419
|
+
|
417
|
420
|
callback(@[
|
418
|
421
|
errMsg ?: [NSNull null],
|
419
|
422
|
rnfbRespType ?: @"",
|
420
|
423
|
respStr ?: [NSNull null]
|
421
|
424
|
]);
|
422
|
|
-
|
|
425
|
+
|
423
|
426
|
respData = nil;
|
424
|
427
|
receivedBytes = 0;
|
425
|
428
|
[session finishTasksAndInvalidate];
|
426
|
|
-
|
|
429
|
+
|
427
|
430
|
}
|
428
|
431
|
|
429
|
432
|
// upload progress handler
|
|
@@ -432,7 +435,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
432
|
435
|
if (totalBytesExpectedToWrite == 0) {
|
433
|
436
|
return;
|
434
|
437
|
}
|
435
|
|
-
|
|
438
|
+
|
436
|
439
|
NSNumber * now = [NSNumber numberWithFloat:((float)totalBytesWritten/(float)totalBytesExpectedToWrite)];
|
437
|
440
|
|
438
|
441
|
if ([self.uploadProgressConfig shouldReport:now]) {
|
|
@@ -465,12 +468,12 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
465
|
468
|
|
466
|
469
|
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
|
467
|
470
|
{
|
468
|
|
-
|
|
471
|
+
|
469
|
472
|
if (followRedirect) {
|
470
|
473
|
if (request.URL) {
|
471
|
474
|
[redirects addObject:[request.URL absoluteString]];
|
472
|
475
|
}
|
473
|
|
-
|
|
476
|
+
|
474
|
477
|
completionHandler(request);
|
475
|
478
|
} else {
|
476
|
479
|
completionHandler(nil);
|