Browse Source

Merge branch '0.10.5'

Ben Hsieh 7 years ago
parent
commit
92455e1ec8

+ 9
- 1
android.js View File

24
     return Promise.reject('RNFetchBlob.actionViewIntent only supports Android.')
24
     return Promise.reject('RNFetchBlob.actionViewIntent only supports Android.')
25
 }
25
 }
26
 
26
 
27
+function getContentIntent(mime:string) {
28
+  if(Platform.OS === 'android')
29
+    return RNFetchBlob.getContentIntent(mime)
30
+  else
31
+    return Promise.reject('RNFetchBlob.getContentIntent only supports Android.')
32
+}
33
+
27
 
34
 
28
 export default {
35
 export default {
29
-  actionViewIntent
36
+  actionViewIntent,
37
+  getContentIntent
30
 }
38
 }

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

1
 package com.RNFetchBlob;
1
 package com.RNFetchBlob;
2
 
2
 
3
+import android.app.Activity;
3
 import android.content.Intent;
4
 import android.content.Intent;
4
 import android.net.Uri;
5
 import android.net.Uri;
6
+import android.util.Log;
5
 
7
 
6
 import com.RNFetchBlob.Utils.RNFBCookieJar;
8
 import com.RNFetchBlob.Utils.RNFBCookieJar;
9
+import com.facebook.react.bridge.ActivityEventListener;
7
 import com.facebook.react.bridge.Callback;
10
 import com.facebook.react.bridge.Callback;
8
 import com.facebook.react.bridge.LifecycleEventListener;
11
 import com.facebook.react.bridge.LifecycleEventListener;
9
 import com.facebook.react.bridge.Promise;
12
 import com.facebook.react.bridge.Promise;
15
 import com.facebook.react.bridge.WritableArray;
18
 import com.facebook.react.bridge.WritableArray;
16
 import com.facebook.react.bridge.WritableMap;
19
 import com.facebook.react.bridge.WritableMap;
17
 
20
 
21
+import java.util.HashMap;
18
 import java.util.Map;
22
 import java.util.Map;
23
+import java.util.UUID;
19
 import java.util.concurrent.LinkedBlockingQueue;
24
 import java.util.concurrent.LinkedBlockingQueue;
20
 import java.util.concurrent.ThreadPoolExecutor;
25
 import java.util.concurrent.ThreadPoolExecutor;
21
 import java.util.concurrent.TimeUnit;
26
 import java.util.concurrent.TimeUnit;
22
 
27
 
28
+import static android.app.Activity.RESULT_OK;
29
+import static com.RNFetchBlob.RNFetchBlobConst.GET_CONTENT_INTENT;
30
+
23
 public class RNFetchBlob extends ReactContextBaseJavaModule {
31
 public class RNFetchBlob extends ReactContextBaseJavaModule {
24
 
32
 
25
     static ReactApplicationContext RCTContext;
33
     static ReactApplicationContext RCTContext;
28
     static LinkedBlockingQueue<Runnable> fsTaskQueue = new LinkedBlockingQueue<>();
36
     static LinkedBlockingQueue<Runnable> fsTaskQueue = new LinkedBlockingQueue<>();
29
     static ThreadPoolExecutor fsThreadPool = new ThreadPoolExecutor(2, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
37
     static ThreadPoolExecutor fsThreadPool = new ThreadPoolExecutor(2, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
30
     static public boolean ActionViewVisible = false;
38
     static public boolean ActionViewVisible = false;
39
+    static HashMap<Integer, Promise> promiseTable = new HashMap<>();
31
 
40
 
32
     public RNFetchBlob(ReactApplicationContext reactContext) {
41
     public RNFetchBlob(ReactApplicationContext reactContext) {
33
 
42
 
34
         super(reactContext);
43
         super(reactContext);
35
 
44
 
36
         RCTContext = reactContext;
45
         RCTContext = reactContext;
46
+        reactContext.addActivityEventListener(new ActivityEventListener() {
47
+            @Override
48
+            public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
49
+                if(requestCode == GET_CONTENT_INTENT && resultCode == RESULT_OK) {
50
+                    Uri d = data.getData();
51
+                    promiseTable.get(GET_CONTENT_INTENT).resolve(d.toString());
52
+                    promiseTable.remove(GET_CONTENT_INTENT);
53
+                }
54
+            }
55
+
56
+            @Override
57
+            public void onNewIntent(Intent intent) {
58
+
59
+            }
60
+        });
37
     }
61
     }
38
 
62
 
39
     @Override
63
     @Override
322
         new RNFetchBlobReq(options, taskId, method, url, headers, null, body, callback).run();
346
         new RNFetchBlobReq(options, taskId, method, url, headers, null, body, callback).run();
323
     }
347
     }
324
 
348
 
349
+    @ReactMethod
350
+    public void getContentIntent(String mime, Promise promise) {
351
+        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
352
+        if(mime != null)
353
+            i.setType(mime);
354
+        else
355
+            i.setType("*/*");
356
+        promiseTable.put(GET_CONTENT_INTENT, promise);
357
+        this.getReactApplicationContext().startActivityForResult(i, GET_CONTENT_INTENT, null);
358
+
359
+    }
360
+
325
 }
361
 }

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

13
     public static final String RNFB_RESPONSE_BASE64 = "base64";
13
     public static final String RNFB_RESPONSE_BASE64 = "base64";
14
     public static final String RNFB_RESPONSE_UTF8  = "utf8";
14
     public static final String RNFB_RESPONSE_UTF8  = "utf8";
15
     public static final String RNFB_RESPONSE_PATH  = "path";
15
     public static final String RNFB_RESPONSE_PATH  = "path";
16
+    public static final Integer GET_CONTENT_INTENT = 99900;
16
 
17
 
17
 }
18
 }

+ 6
- 3
android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

234
 
234
 
235
             InputStream fs;
235
             InputStream fs;
236
             if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
236
             if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
237
-                fs = RNFetchBlob.RCTContext.getAssets().open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));
237
+                fs = RNFetchBlob.RCTContext.getAssets()
238
+                        .open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));
238
             }
239
             }
239
             else {
240
             else {
240
                 fs = new FileInputStream(new File(path));
241
                 fs = new FileInputStream(new File(path));
249
                 while ((cursor = fs.read(buffer)) != -1) {
250
                 while ((cursor = fs.read(buffer)) != -1) {
250
                     encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
251
                     encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
251
                     String chunk = new String(buffer);
252
                     String chunk = new String(buffer);
252
-                    if(cursor != bufferSize)
253
+                    if(cursor != bufferSize) {
253
                         chunk = chunk.substring(0, cursor);
254
                         chunk = chunk.substring(0, cursor);
255
+                    }
254
                     emitStreamEvent(streamId, "data", chunk);
256
                     emitStreamEvent(streamId, "data", chunk);
255
                     if(tick > 0)
257
                     if(tick > 0)
256
                         SystemClock.sleep(tick);
258
                         SystemClock.sleep(tick);
292
             buffer = null;
294
             buffer = null;
293
 
295
 
294
         } catch (Exception err) {
296
         } catch (Exception err) {
295
-            emitStreamEvent(streamId, "error", "Failed to convert data to "+encoding+" encoded string, this might due to the source data is not able to convert using this encoding.");
297
+            emitStreamEvent(streamId, "warn", "Failed to convert data to "+encoding+" encoded string, this might due to the source data is not able to convert using this encoding.");
298
+            err.printStackTrace();
296
         }
299
         }
297
     }
300
     }
298
 
301
 

+ 18
- 8
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

629
                 DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
629
                 DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
630
                 dm.query(query);
630
                 dm.query(query);
631
                 Cursor c = dm.query(query);
631
                 Cursor c = dm.query(query);
632
-                String error = null;
632
+
633
+
633
                 String filePath = null;
634
                 String filePath = null;
634
                 // the file exists in media content database
635
                 // the file exists in media content database
635
                 if (c.moveToFirst()) {
636
                 if (c.moveToFirst()) {
637
+                    // #297 handle failed request
638
+                    int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
639
+                    if(statusCode == DownloadManager.STATUS_FAILED) {
640
+                        this.callback.invoke("Download manager failed to download from  " + this.url + ". Statu Code = " + statusCode, null, null);
641
+                        return;
642
+                    }
636
                     String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
643
                     String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
637
-                    Uri uri = Uri.parse(contentUri);
638
-                    Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
639
-                    // use default destination of DownloadManager
640
-                    if (cursor != null) {
641
-                        cursor.moveToFirst();
642
-                        filePath = cursor.getString(0);
644
+                    if (contentUri != null) {
645
+                        Uri uri = Uri.parse(contentUri);
646
+                        Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
647
+                        // use default destination of DownloadManager
648
+                        if (cursor != null) {
649
+                            cursor.moveToFirst();
650
+                            filePath = cursor.getString(0);
651
+                        }
643
                     }
652
                     }
644
                 }
653
                 }
645
                 // When the file is not found in media content database, check if custom path exists
654
                 // When the file is not found in media content database, check if custom path exists
653
                             this.callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, customDest);
662
                             this.callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, customDest);
654
 
663
 
655
                     } catch(Exception ex) {
664
                     } catch(Exception ex) {
656
-                        error = ex.getLocalizedMessage();
665
+                        ex.printStackTrace();
666
+                        this.callback.invoke(ex.getLocalizedMessage(), null);
657
                     }
667
                     }
658
                 }
668
                 }
659
                 else {
669
                 else {

+ 29
- 13
ios/RNFetchBlob/RNFetchBlob.m View File

314
 #pragma mark - fs.stat
314
 #pragma mark - fs.stat
315
 RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
315
 RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
316
 {
316
 {
317
-    
317
+
318
     [RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
318
     [RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
319
         __block NSMutableArray * result;
319
         __block NSMutableArray * result;
320
         if(path != nil)
320
         if(path != nil)
323
             BOOL exist = nil;
323
             BOOL exist = nil;
324
             BOOL isDir = nil;
324
             BOOL isDir = nil;
325
             NSError * error = nil;
325
             NSError * error = nil;
326
-            
326
+
327
             exist = [fm fileExistsAtPath:path isDirectory:&isDir];
327
             exist = [fm fileExistsAtPath:path isDirectory:&isDir];
328
             if(exist == NO) {
328
             if(exist == NO) {
329
                 callback(@[[NSString stringWithFormat:@"failed to stat path `%@` for it is not exist or it is not exist", path]]);
329
                 callback(@[[NSString stringWithFormat:@"failed to stat path `%@` for it is not exist or it is not exist", path]]);
330
                 return ;
330
                 return ;
331
             }
331
             }
332
             result = [RNFetchBlobFS stat:path error:&error];
332
             result = [RNFetchBlobFS stat:path error:&error];
333
-            
333
+
334
             if(error == nil)
334
             if(error == nil)
335
                 callback(@[[NSNull null], result]);
335
                 callback(@[[NSNull null], result]);
336
             else
336
             else
389
 #pragma mark - fs.cp
389
 #pragma mark - fs.cp
390
 RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
390
 RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
391
 {
391
 {
392
-    
392
+
393
 //    path = [RNFetchBlobFS getPathOfAsset:path];
393
 //    path = [RNFetchBlobFS getPathOfAsset:path];
394
     [RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
394
     [RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
395
         NSError * error = nil;
395
         NSError * error = nil;
401
         else
401
         else
402
         {
402
         {
403
             BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
403
             BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
404
-            
404
+
405
             if(error == nil)
405
             if(error == nil)
406
                 callback(@[[NSNull null], @YES]);
406
                 callback(@[[NSNull null], @YES]);
407
             else
407
             else
408
                 callback(@[[error localizedDescription], @NO]);
408
                 callback(@[[error localizedDescription], @NO]);
409
         }
409
         }
410
     }];
410
     }];
411
-    
411
+
412
 }
412
 }
413
 
413
 
414
 
414
 
470
         else
470
         else
471
             bufferSize = 4096;
471
             bufferSize = 4096;
472
     }
472
     }
473
-    
473
+
474
     dispatch_async(fsQueue, ^{
474
     dispatch_async(fsQueue, ^{
475
         [RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
475
         [RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
476
     });
476
     });
496
 #pragma mark - net.enableProgressReport
496
 #pragma mark - net.enableProgressReport
497
 RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
497
 RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
498
 {
498
 {
499
-    
499
+
500
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
500
     RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
501
     [RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
501
     [RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
502
 }
502
 }
523
     UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
523
     UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
524
     documentController.delegate = self;
524
     documentController.delegate = self;
525
     if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
525
     if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
526
-        dispatch_sync(dispatch_get_main_queue(), ^{
527
-            [documentController  presentOptionsMenuFromRect:rootCtrl.view.bounds inView:rootCtrl.view animated:YES];
528
-        });
526
+      CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
527
+      dispatch_sync(dispatch_get_main_queue(), ^{
528
+          [documentController  presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
529
+      });
529
         resolve(@[[NSNull null]]);
530
         resolve(@[[NSNull null]]);
530
     } else {
531
     } else {
531
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
532
         reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
541
     // NSURL * url = [[NSURL alloc] initWithString:uri];
542
     // NSURL * url = [[NSURL alloc] initWithString:uri];
542
     documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
543
     documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
543
     documentController.delegate = self;
544
     documentController.delegate = self;
544
-    
545
+
545
     if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
546
     if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
546
         dispatch_sync(dispatch_get_main_queue(), ^{
547
         dispatch_sync(dispatch_get_main_queue(), ^{
547
             [documentController presentPreviewAnimated:YES];
548
             [documentController presentPreviewAnimated:YES];
564
     } else {
565
     } else {
565
         reject(@"RNFetchBlob could not open document", [error description], nil);
566
         reject(@"RNFetchBlob could not open document", [error description], nil);
566
     }
567
     }
567
-    
568
+
568
 }
569
 }
569
 
570
 
570
 
571
 
580
 }
581
 }
581
 
582
 
582
 # pragma mark - getCookies
583
 # pragma mark - getCookies
584
+
583
 RCT_EXPORT_METHOD(getCookies:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
585
 RCT_EXPORT_METHOD(getCookies:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
584
 {
586
 {
585
     resolve([RNFetchBlobNetwork getCookies:url]);
587
     resolve([RNFetchBlobNetwork getCookies:url]);
586
 }
588
 }
587
 
589
 
590
+# pragma mark - removeCookie
591
+
592
+RCT_EXPORT_METHOD(removeCookies:(NSString *)domain resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
593
+{
594
+    NSError * err = nil;
595
+    [RNFetchBlobNetwork removeCookies:domain error:&err];
596
+    if(err)
597
+        reject(@"RNFetchBlob failed to remove cookie", @"RNFetchBlob failed to remove cookie", nil);
598
+    else
599
+        resolve(@[[NSNull null]]);
600
+}
601
+
588
 # pragma mark - check expired network events
602
 # pragma mark - check expired network events
589
 
603
 
590
 RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
604
 RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
593
 }
607
 }
594
 
608
 
595
 
609
 
610
+
611
+
596
 @end
612
 @end

+ 3
- 6
ios/RNFetchBlobFS.m View File

758
 
758
 
759
 +(void) df:(RCTResponseSenderBlock)callback
759
 +(void) df:(RCTResponseSenderBlock)callback
760
 {
760
 {
761
-    uint64_t totalSpace = 0;
762
-    uint64_t totalFreeSpace = 0;
763
     NSError *error = nil;
761
     NSError *error = nil;
764
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
762
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
765
     NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
763
     NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
767
     if (dictionary) {
765
     if (dictionary) {
768
         NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
766
         NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
769
         NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
767
         NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
770
-        totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
771
-        totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
768
+        
772
         callback(@[[NSNull null], @{
769
         callback(@[[NSNull null], @{
773
-                  @"free" : [NSString stringWithFormat:@"%ld", totalFreeSpace],
774
-                  @"total" : [NSString stringWithFormat:@"%ld", totalSpace]
770
+                  @"free" : freeFileSystemSizeInBytes,
771
+                  @"total" : fileSystemSizeInBytes,
775
                 }]);
772
                 }]);
776
     } else {
773
     } else {
777
         callback(@[@"failed to get storage usage."]);
774
         callback(@[@"failed to get storage usage."]);

+ 2
- 1
ios/RNFetchBlobNetwork.h View File

49
 - (nullable id) init;
49
 - (nullable id) init;
50
 - (void) sendRequest;
50
 - (void) sendRequest;
51
 - (void) sendRequest:(NSDictionary  * _Nullable )options contentLength:(long)contentLength bridge:(RCTBridge * _Nullable)bridgeRef taskId:(NSString * _Nullable)taskId withRequest:(NSURLRequest * _Nullable)req callback:(_Nullable RCTResponseSenderBlock) callback;
51
 - (void) sendRequest:(NSDictionary  * _Nullable )options contentLength:(long)contentLength bridge:(RCTBridge * _Nullable)bridgeRef taskId:(NSString * _Nullable)taskId withRequest:(NSURLRequest * _Nullable)req callback:(_Nullable RCTResponseSenderBlock) callback;
52
++ (void) removeCookies:(NSString *) domain error:(NSError **)error;
52
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config;
53
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config;
53
 + (void) enableUploadProgress:(NSString *) taskId config:(RNFetchBlobProgress *)config;
54
 + (void) enableUploadProgress:(NSString *) taskId config:(RNFetchBlobProgress *)config;
54
-+ (NSArray *) getCookies:(NSString *) url;
55
++ (NSDictionary *) getCookies:(NSString *) url;
55
 
56
 
56
 
57
 
57
 
58
 

+ 85
- 48
ios/RNFetchBlobNetwork.m View File

37
 
37
 
38
 NSMapTable * taskTable;
38
 NSMapTable * taskTable;
39
 NSMapTable * expirationTable;
39
 NSMapTable * expirationTable;
40
-NSMapTable * cookiesTable;
41
 NSMutableDictionary * progressTable;
40
 NSMutableDictionary * progressTable;
42
 NSMutableDictionary * uploadProgressTable;
41
 NSMutableDictionary * uploadProgressTable;
43
 
42
 
59
     {
58
     {
60
         uploadProgressTable = [[NSMutableDictionary alloc] init];
59
         uploadProgressTable = [[NSMutableDictionary alloc] init];
61
     }
60
     }
62
-    if(cookiesTable == nil)
63
-    {
64
-        cookiesTable = [[NSMapTable alloc] init];
65
-    }
66
 }
61
 }
67
 
62
 
68
 
63
 
116
     return self;
111
     return self;
117
 }
112
 }
118
 
113
 
119
-+ (NSArray *) getCookies:(NSString *) url
120
-{
121
-    NSString * hostname = [[NSURL URLWithString:url] host];
122
-    NSMutableArray * cookies = [NSMutableArray new];
123
-    NSArray * list = [cookiesTable objectForKey:hostname];
124
-    for(NSHTTPCookie * cookie in list)
125
-    {
126
-        NSMutableString * cookieStr = [[NSMutableString alloc] init];
127
-        [cookieStr appendString:cookie.name];
128
-        [cookieStr appendString:@"="];
129
-        [cookieStr appendString:cookie.value];
130
-
131
-        if(cookie.expiresDate == nil) {
132
-            [cookieStr appendString:@"; max-age=0"];
133
-        }
134
-        else {
135
-            [cookieStr appendString:@"; expires="];
136
-            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
137
-            [dateFormatter setDateFormat:@"EEE, dd MM yyyy HH:mm:ss ZZZ"];
138
-            NSString *strDate = [dateFormatter stringFromDate:cookie.expiresDate];
139
-            [cookieStr appendString:strDate];
140
-        }
141
-
142
-
143
-        [cookieStr appendString:@"; domain="];
144
-        [cookieStr appendString:hostname];
145
-        [cookieStr appendString:@"; path="];
146
-        [cookieStr appendString:cookie.path];
147
-
148
-
149
-        if (cookie.isSecure) {
150
-            [cookieStr appendString:@"; secure"];
151
-        }
152
-
153
-        if (cookie.isHTTPOnly) {
154
-            [cookieStr appendString:@"; httponly"];
155
-        }
156
-        [cookies addObject:cookieStr];
157
-    }
158
-    return cookies;
159
-}
160
-
161
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config
114
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config
162
 {
115
 {
163
     if(progressTable == nil)
116
     if(progressTable == nil)
418
         // # 153 get cookies
371
         // # 153 get cookies
419
         if(response.URL != nil)
372
         if(response.URL != nil)
420
         {
373
         {
374
+            NSHTTPCookieStorage * cookieStore = [NSHTTPCookieStorage sharedHTTPCookieStorage];
421
             NSArray<NSHTTPCookie *> * cookies = [NSHTTPCookie cookiesWithResponseHeaderFields: headers forURL:response.URL];
375
             NSArray<NSHTTPCookie *> * cookies = [NSHTTPCookie cookiesWithResponseHeaderFields: headers forURL:response.URL];
422
             if(cookies != nil && [cookies count] > 0) {
376
             if(cookies != nil && [cookies count] > 0) {
423
-                [cookiesTable setObject:cookies forKey:response.URL.host];
377
+                [cookieStore setCookies:cookies forURL:response.URL mainDocumentURL:nil];
424
             }
378
             }
425
         }
379
         }
426
 
380
 
624
     }
578
     }
625
 }
579
 }
626
 
580
 
581
+# pragma mark - cookies handling API
582
+
583
++ (NSDictionary *) getCookies:(NSString *) domain
584
+{
585
+    NSMutableDictionary * result = [NSMutableDictionary new];
586
+    NSHTTPCookieStorage * cookieStore = [NSHTTPCookieStorage sharedHTTPCookieStorage];
587
+    for(NSHTTPCookie * cookie in [cookieStore cookies])
588
+    {
589
+        NSString * cDomain = [cookie domain];
590
+        if([result objectForKey:cDomain] == nil)
591
+        {
592
+            [result setObject:[NSMutableArray new] forKey:cDomain];
593
+        }
594
+        if([cDomain isEqualToString:domain] || [domain length] == 0)
595
+        {
596
+            NSMutableString * cookieStr = [[NSMutableString alloc] init];
597
+            cookieStr = [[self class] getCookieString:cookie];
598
+            NSMutableArray * ary = [result objectForKey:cDomain];
599
+            [ary addObject:cookieStr];
600
+            [result setObject:ary forKey:cDomain];
601
+        }
602
+    }
603
+    return result;
604
+}
605
+
606
+// remove cookies for given domain, if domain is empty remove all cookies in shared cookie storage.
607
++ (void) removeCookies:(NSString *) domain error:(NSError **)error
608
+{
609
+    @try
610
+    {
611
+        NSHTTPCookieStorage * cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
612
+        for(NSHTTPCookie * cookie in [cookies cookies])
613
+        {
614
+            BOOL shouldRemove = domain == nil || [domain length] < 1 || [[cookie domain] isEqualToString:domain];
615
+            if(shouldRemove)
616
+            {
617
+                [cookies deleteCookie:cookie];
618
+            }
619
+        }
620
+    }
621
+    @catch(NSError * err)
622
+    {
623
+        *error = err;
624
+    }
625
+}
626
+
627
+// convert NSHTTPCookie to string
628
++ (NSString *) getCookieString:(NSHTTPCookie *) cookie
629
+{
630
+    NSMutableString * cookieStr = [[NSMutableString alloc] init];
631
+    [cookieStr appendString:cookie.name];
632
+    [cookieStr appendString:@"="];
633
+    [cookieStr appendString:cookie.value];
634
+    
635
+    if(cookie.expiresDate == nil) {
636
+        [cookieStr appendString:@"; max-age=0"];
637
+    }
638
+    else {
639
+        [cookieStr appendString:@"; expires="];
640
+        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
641
+        [dateFormatter setDateFormat:@"EEE, dd MM yyyy HH:mm:ss ZZZ"];
642
+        NSString *strDate = [dateFormatter stringFromDate:cookie.expiresDate];
643
+        [cookieStr appendString:strDate];
644
+    }
645
+    
646
+    
647
+    [cookieStr appendString:@"; domain="];
648
+    [cookieStr appendString: [cookie domain]];
649
+    [cookieStr appendString:@"; path="];
650
+    [cookieStr appendString:cookie.path];
651
+    
652
+    
653
+    if (cookie.isSecure) {
654
+        [cookieStr appendString:@"; secure"];
655
+    }
656
+    
657
+    if (cookie.isHTTPOnly) {
658
+        [cookieStr appendString:@"; httponly"];
659
+    }
660
+    return cookieStr;
661
+
662
+}
663
+
627
 + (void) cancelRequest:(NSString *)taskId
664
 + (void) cancelRequest:(NSString *)taskId
628
 {
665
 {
629
     NSURLSessionDataTask * task = [taskTable objectForKey:taskId];
666
     NSURLSessionDataTask * task = [taskTable objectForKey:taskId];

+ 6
- 4
ios/RNFetchBlobReqBuilder.m View File

99
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
99
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
100
         NSMutableData * blobData;
100
         NSMutableData * blobData;
101
         long size = -1;
101
         long size = -1;
102
-        // if method is POST or PUT, convert data string format
103
-        if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
102
+        // if method is POST, PUT or PATCH, convert data string format
103
+        if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"] || [[method lowercaseString] isEqualToString:@"patch"]) {
104
             // generate octet-stream body
104
             // generate octet-stream body
105
             if(body != nil) {
105
             if(body != nil) {
106
                 __block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
106
                 __block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
201
                 RCTLogWarn(@"RNFetchBlob multipart request builder has found a field without `data` or `name` property, the field will be removed implicitly.");
201
                 RCTLogWarn(@"RNFetchBlob multipart request builder has found a field without `data` or `name` property, the field will be removed implicitly.");
202
                 return;
202
                 return;
203
             }
203
             }
204
-            contentType = contentType == nil ? @"application/octet-stream" : contentType;
204
+
205
             // field is a text field
205
             // field is a text field
206
             if([field valueForKey:@"filename"] == nil || content == nil) {
206
             if([field valueForKey:@"filename"] == nil || content == nil) {
207
+                contentType = contentType == nil ? @"text/plain" : contentType;
207
                 [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
208
                 [formData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
208
                 [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", name] dataUsingEncoding:NSUTF8StringEncoding]];
209
                 [formData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", name] dataUsingEncoding:NSUTF8StringEncoding]];
209
-                [formData appendData:[[NSString stringWithFormat:@"Content-Type: text/plain\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
210
+                [formData appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]];
210
                 [formData appendData:[[NSString stringWithFormat:@"%@\r\n", content] dataUsingEncoding:NSUTF8StringEncoding]];
211
                 [formData appendData:[[NSString stringWithFormat:@"%@\r\n", content] dataUsingEncoding:NSUTF8StringEncoding]];
211
             }
212
             }
212
             // field contains a file
213
             // field contains a file
213
             else {
214
             else {
215
+                contentType = contentType == nil ? @"application/octet-stream" : contentType;
214
                 NSMutableData * blobData;
216
                 NSMutableData * blobData;
215
                 if(content != nil)
217
                 if(content != nil)
216
                 {
218
                 {