|
23 | 23 | //
|
24 | 24 | ////////////////////////////////////////
|
25 | 25 |
|
26 |
| -NSMutableDictionary * taskTable; |
| 26 | +NSMapTable * taskTable; |
27 | 27 | NSMutableDictionary * progressTable;
|
28 | 28 | NSMutableDictionary * uploadProgressTable;
|
29 | 29 |
|
| 30 | + |
30 | 31 | @interface RNFetchBlobNetwork ()
|
31 | 32 | {
|
32 | 33 | BOOL * respFile;
|
33 | 34 | NSString * destPath;
|
34 | 35 | NSOutputStream * writeStream;
|
35 | 36 | long bodyLength;
|
36 | 37 | NSMutableDictionary * respInfo;
|
| 38 | + NSInteger respStatus; |
37 | 39 | }
|
38 | 40 |
|
39 | 41 | @end
|
@@ -61,7 +63,7 @@ - (id)init {
|
61 | 63 | taskQueue.maxConcurrentOperationCount = 10;
|
62 | 64 | }
|
63 | 65 | if(taskTable == nil) {
|
64 |
| - taskTable = [[NSMutableDictionary alloc] init]; |
| 66 | + taskTable = [[NSMapTable alloc] init]; |
65 | 67 | }
|
66 | 68 | if(progressTable == nil)
|
67 | 69 | {
|
@@ -139,6 +141,7 @@ - (void) sendRequest:(__weak NSDictionary * _Nullable )options
|
139 | 141 | {
|
140 | 142 | defaultConfigObject.timeoutIntervalForRequest = [[options valueForKey:@"timeout"] floatValue]/1000;
|
141 | 143 | }
|
| 144 | + defaultConfigObject.HTTPMaximumConnectionsPerHost = 10; |
142 | 145 | session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:taskQueue];
|
143 | 146 | if(path != nil || [self.options valueForKey:CONFIG_USE_TEMP]!= nil)
|
144 | 147 | {
|
@@ -193,6 +196,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
|
193 | 196 |
|
194 | 197 | NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
|
195 | 198 | NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
|
| 199 | + respStatus = statusCode; |
196 | 200 | if ([response respondsToSelector:@selector(allHeaderFields)])
|
197 | 201 | {
|
198 | 202 | NSDictionary *headers = [httpResponse allHeaderFields];
|
@@ -242,7 +246,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
|
242 | 246 | @"respType" : respType,
|
243 | 247 | @"timeout" : @NO,
|
244 | 248 | @"status": [NSString stringWithFormat:@"%d", statusCode ]
|
245 |
| - }; |
| 249 | + }; |
246 | 250 |
|
247 | 251 | [self.bridge.eventDispatcher
|
248 | 252 | sendDeviceEventWithName: EVENT_STATE_CHANGE
|
@@ -270,6 +274,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
|
270 | 274 | NSLog(@"write file error");
|
271 | 275 | }
|
272 | 276 | }
|
| 277 | + |
273 | 278 | completionHandler(NSURLSessionResponseAllow);
|
274 | 279 | }
|
275 | 280 |
|
@@ -312,42 +317,66 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
|
312 | 317 | {
|
313 | 318 |
|
314 | 319 | self.error = error;
|
315 |
| - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; |
316 |
| - |
| 320 | + NSString * errMsg = [NSNull null]; |
| 321 | + NSString * respStr = [NSNull null]; |
317 | 322 | NSString * respType = [respInfo valueForKey:@"respType"];
|
318 |
| - if(error != nil) { |
319 |
| - NSLog([error localizedDescription]); |
| 323 | + |
| 324 | + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; |
| 325 | + if(error != nil) |
| 326 | + { |
| 327 | + errMsg = [error localizedDescription]; |
| 328 | + } |
| 329 | + if(respInfo == nil) |
| 330 | + { |
| 331 | + respInfo = [NSNull null]; |
320 | 332 | }
|
321 | 333 |
|
322 |
| - if(respFile == YES) |
| 334 | + // Fix #72 response with status code 200 ~ 299 considered as success |
| 335 | + if(respStatus> 299 || respStatus < 200) |
| 336 | + { |
| 337 | + errMsg = [NSString stringWithFormat:@"Request failed, status %d", respStatus]; |
| 338 | + } |
| 339 | + else |
323 | 340 | {
|
324 |
| - [writeStream close]; |
325 |
| - callback(@[error == nil ? [NSNull null] : [error localizedDescription], |
326 |
| - respInfo == nil ? [NSNull null] : respInfo, |
327 |
| - destPath |
328 |
| - ]); |
| 341 | + if(respFile == YES) |
| 342 | + { |
| 343 | + [writeStream close]; |
| 344 | + respStr = destPath; |
| 345 | + } |
| 346 | + // base64 response |
| 347 | + else { |
| 348 | + // #73 fix unicode data encoding issue : |
| 349 | + // when response type is BASE64, we should first try to encode the response data to UTF8 format |
| 350 | + // if it turns out not to be `nil` that means the response data contains valid UTF8 string, |
| 351 | + // in order to properly encode the UTF8 string, use URL encoding before BASE64 encoding. |
| 352 | + NSString * urlEncoded = [[[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding] |
| 353 | + stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; |
| 354 | + NSString * base64 = @""; |
| 355 | + if(urlEncoded != nil) |
| 356 | + base64 = [[urlEncoded dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]; |
| 357 | + else |
| 358 | + base64 = [respData base64EncodedStringWithOptions:0]; |
| 359 | + respStr = base64; |
| 360 | + |
| 361 | + } |
329 | 362 | }
|
330 |
| - // base64 response |
331 |
| - else { |
332 |
| - NSString * utf8 = [[[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; |
333 |
| - NSString * base64 = @""; |
334 |
| - if(utf8 != nil) |
335 |
| - base64 = [[utf8 dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0]; |
| 363 | + |
| 364 | + callback(@[ errMsg, respInfo, respStr ]); |
| 365 | + |
| 366 | + @synchronized(taskTable, uploadProgressTable, progressTable) |
| 367 | + { |
| 368 | + if([taskTable objectForKey:taskId] == nil) |
| 369 | + NSLog(@"object released."); |
336 | 370 | else
|
337 |
| - base64 = [respData base64EncodedStringWithOptions:0]; |
338 |
| - callback(@[error == nil ? [NSNull null] : [error localizedDescription], |
339 |
| - respInfo == nil ? [NSNull null] : respInfo, |
340 |
| - base64 |
341 |
| - ]); |
342 |
| - |
| 371 | + [taskTable removeObjectForKey:taskId]; |
| 372 | + [uploadProgressTable removeObjectForKey:taskId]; |
| 373 | + [progressTable removeObjectForKey:taskId]; |
343 | 374 | }
|
344 | 375 |
|
345 |
| - [taskTable removeObjectForKey:taskId]; |
346 |
| - [uploadProgressTable removeObjectForKey:taskId]; |
347 |
| - [progressTable removeObjectForKey:taskId]; |
348 | 376 | respData = nil;
|
349 | 377 | receivedBytes = 0;
|
350 | 378 | [session finishTasksAndInvalidate];
|
| 379 | + |
351 | 380 | }
|
352 | 381 |
|
353 | 382 | // upload progress handler
|
|
0 commit comments