瀏覽代碼

Android share cookies w/ RN, remove cookie utils (#388)

Jacob Lauritzen 7 年之前
父節點
當前提交
4ea868fe79

+ 20
- 37
android/src/main/java/com/RNFetchBlob/RNFetchBlob.java 查看文件

3
 import android.app.Activity;
3
 import android.app.Activity;
4
 import android.content.Intent;
4
 import android.content.Intent;
5
 import android.net.Uri;
5
 import android.net.Uri;
6
-import android.util.Log;
7
 
6
 
8
-import com.RNFetchBlob.Utils.RNFBCookieJar;
9
 import com.facebook.react.bridge.ActivityEventListener;
7
 import com.facebook.react.bridge.ActivityEventListener;
10
 import com.facebook.react.bridge.Callback;
8
 import com.facebook.react.bridge.Callback;
11
 import com.facebook.react.bridge.LifecycleEventListener;
9
 import com.facebook.react.bridge.LifecycleEventListener;
15
 import com.facebook.react.bridge.ReactMethod;
13
 import com.facebook.react.bridge.ReactMethod;
16
 import com.facebook.react.bridge.ReadableArray;
14
 import com.facebook.react.bridge.ReadableArray;
17
 import com.facebook.react.bridge.ReadableMap;
15
 import com.facebook.react.bridge.ReadableMap;
18
-import com.facebook.react.bridge.WritableArray;
19
-import com.facebook.react.bridge.WritableMap;
16
+
17
+// Cookies
18
+import com.facebook.react.modules.network.ForwardingCookieHandler;
19
+import com.facebook.react.modules.network.CookieJarContainer;
20
+import com.facebook.react.modules.network.OkHttpClientProvider;
21
+import okhttp3.OkHttpClient;
22
+import okhttp3.JavaNetCookieJar;
20
 
23
 
21
 import java.util.HashMap;
24
 import java.util.HashMap;
22
 import java.util.Map;
25
 import java.util.Map;
23
-import java.util.UUID;
24
 import java.util.concurrent.LinkedBlockingQueue;
26
 import java.util.concurrent.LinkedBlockingQueue;
25
 import java.util.concurrent.ThreadPoolExecutor;
27
 import java.util.concurrent.ThreadPoolExecutor;
26
 import java.util.concurrent.TimeUnit;
28
 import java.util.concurrent.TimeUnit;
30
 
32
 
31
 public class RNFetchBlob extends ReactContextBaseJavaModule {
33
 public class RNFetchBlob extends ReactContextBaseJavaModule {
32
 
34
 
35
+    // Cookies
36
+    private final ForwardingCookieHandler mCookieHandler;
37
+    private final CookieJarContainer mCookieJarContainer;
38
+    private final OkHttpClient mClient;
39
+
33
     static ReactApplicationContext RCTContext;
40
     static ReactApplicationContext RCTContext;
34
     static LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
41
     static LinkedBlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
35
     static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
42
     static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 5000, TimeUnit.MILLISECONDS, taskQueue);
42
 
49
 
43
         super(reactContext);
50
         super(reactContext);
44
 
51
 
52
+        mClient = OkHttpClientProvider.getOkHttpClient();
53
+        mCookieHandler = new ForwardingCookieHandler(reactContext);
54
+        mCookieJarContainer = (CookieJarContainer) mClient.cookieJar();
55
+        mCookieJarContainer.setCookieJar(new JavaNetCookieJar(mCookieHandler));
56
+
45
         RCTContext = reactContext;
57
         RCTContext = reactContext;
46
         reactContext.addActivityEventListener(new ActivityEventListener() {
58
         reactContext.addActivityEventListener(new ActivityEventListener() {
47
             @Override
59
             @Override
252
 
264
 
253
     }
265
     }
254
 
266
 
255
-    @ReactMethod
256
-    /**
257
-     * Get cookies belongs specific host.
258
-     * @param host String domain name.
259
-     */
260
-    public void getCookies(String domain, Promise promise) {
261
-        try {
262
-            WritableMap cookies = RNFBCookieJar.getCookies(domain);
263
-            promise.resolve(cookies);
264
-        } catch(Exception err) {
265
-            promise.reject("RNFetchBlob.getCookies", err.getMessage());
266
-        }
267
-    }
268
-
269
-    @ReactMethod
270
-    /**
271
-     * Remove cookies for specific domain
272
-     * @param domain String of the domain
273
-     * @param promise JSC promise injected by RN
274
-     */
275
-    public void removeCookies(String domain, Promise promise) {
276
-        try {
277
-            RNFBCookieJar.removeCookies(domain);
278
-            promise.resolve(null);
279
-        } catch(Exception err) {
280
-            promise.reject("RNFetchBlob.removeCookies", err.getMessage());
281
-        }
282
-    }
283
-
284
     @ReactMethod
267
     @ReactMethod
285
     /**
268
     /**
286
      * @param path Stream file path
269
      * @param path Stream file path
338
 
321
 
339
     @ReactMethod
322
     @ReactMethod
340
     public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
323
     public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
341
-        new RNFetchBlobReq(options, taskId, method, url, headers, body, null, callback).run();
342
-    }
324
+        new RNFetchBlobReq(options, taskId, method, url, headers, body, null, mClient, callback).run();
325
+}
343
 
326
 
344
     @ReactMethod
327
     @ReactMethod
345
     public void fetchBlobForm(ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
328
     public void fetchBlobForm(ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
346
-        new RNFetchBlobReq(options, taskId, method, url, headers, null, body, callback).run();
329
+        new RNFetchBlobReq(options, taskId, method, url, headers, null, body, mClient, callback).run();
347
     }
330
     }
348
 
331
 
349
     @ReactMethod
332
     @ReactMethod

+ 5
- 10
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java 查看文件

11
 
11
 
12
 import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
12
 import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
13
 import com.RNFetchBlob.Response.RNFetchBlobFileResp;
13
 import com.RNFetchBlob.Response.RNFetchBlobFileResp;
14
-import com.RNFetchBlob.Utils.RNFBCookieJar;
15
 import com.facebook.react.bridge.Arguments;
14
 import com.facebook.react.bridge.Arguments;
16
 import com.facebook.react.bridge.Callback;
15
 import com.facebook.react.bridge.Callback;
17
 import com.facebook.react.bridge.ReactApplicationContext;
16
 import com.facebook.react.bridge.ReactApplicationContext;
21
 import com.facebook.react.bridge.WritableArray;
20
 import com.facebook.react.bridge.WritableArray;
22
 import com.facebook.react.bridge.WritableMap;
21
 import com.facebook.react.bridge.WritableMap;
23
 import com.facebook.react.modules.core.DeviceEventManagerModule;
22
 import com.facebook.react.modules.core.DeviceEventManagerModule;
23
+import com.facebook.react.modules.network.OkHttpClientProvider;
24
 
24
 
25
 import java.io.File;
25
 import java.io.File;
26
 import java.io.FileOutputStream;
26
 import java.io.FileOutputStream;
27
 import java.io.IOException;
27
 import java.io.IOException;
28
 import java.io.InputStream;
28
 import java.io.InputStream;
29
-import java.net.CookieHandler;
30
-import java.net.CookieManager;
31
-import java.net.CookiePolicy;
32
 import java.net.MalformedURLException;
29
 import java.net.MalformedURLException;
33
 import java.net.SocketException;
30
 import java.net.SocketException;
34
 import java.net.SocketTimeoutException;
31
 import java.net.SocketTimeoutException;
43
 
40
 
44
 import okhttp3.Call;
41
 import okhttp3.Call;
45
 import okhttp3.ConnectionPool;
42
 import okhttp3.ConnectionPool;
46
-import okhttp3.CookieJar;
47
 import okhttp3.Headers;
43
 import okhttp3.Headers;
48
 import okhttp3.Interceptor;
44
 import okhttp3.Interceptor;
49
 import okhttp3.MediaType;
45
 import okhttp3.MediaType;
98
     WritableMap respInfo;
94
     WritableMap respInfo;
99
     boolean timeout = false;
95
     boolean timeout = false;
100
     ArrayList<String> redirects = new ArrayList<>();
96
     ArrayList<String> redirects = new ArrayList<>();
97
+    OkHttpClient client;
101
 
98
 
102
-    public RNFetchBlobReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, final Callback callback) {
99
+    public RNFetchBlobReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, OkHttpClient client, final Callback callback) {
103
         this.method = method.toUpperCase();
100
         this.method = method.toUpperCase();
104
         this.options = new RNFetchBlobConfig(options);
101
         this.options = new RNFetchBlobConfig(options);
105
         this.taskId = taskId;
102
         this.taskId = taskId;
108
         this.callback = callback;
105
         this.callback = callback;
109
         this.rawRequestBody = body;
106
         this.rawRequestBody = body;
110
         this.rawRequestBodyArray = arrayBody;
107
         this.rawRequestBodyArray = arrayBody;
108
+        this.client = client;
111
 
109
 
112
         if(this.options.fileCache || this.options.path != null)
110
         if(this.options.fileCache || this.options.path != null)
113
             responseType = ResponseType.FileStorage;
111
             responseType = ResponseType.FileStorage;
196
             if (this.options.trusty) {
194
             if (this.options.trusty) {
197
                 clientBuilder = RNFetchBlobUtils.getUnsafeOkHttpClient();
195
                 clientBuilder = RNFetchBlobUtils.getUnsafeOkHttpClient();
198
             } else {
196
             } else {
199
-                clientBuilder = new OkHttpClient.Builder();
197
+                clientBuilder = client.newBuilder();
200
             }
198
             }
201
 
199
 
202
             final Request.Builder builder = new Request.Builder();
200
             final Request.Builder builder = new Request.Builder();
297
             }
295
             }
298
 
296
 
299
             // #156 fix cookie issue
297
             // #156 fix cookie issue
300
-
301
-
302
             final Request req = builder.build();
298
             final Request req = builder.build();
303
-            clientBuilder.cookieJar(new RNFBCookieJar());
304
             clientBuilder.addNetworkInterceptor(new Interceptor() {
299
             clientBuilder.addNetworkInterceptor(new Interceptor() {
305
                 @Override
300
                 @Override
306
                 public Response intercept(Chain chain) throws IOException {
301
                 public Response intercept(Chain chain) throws IOException {

+ 2
- 2
android/src/main/java/com/RNFetchBlob/RNFetchBlobUtils.java 查看文件

52
                 .emit(RNFetchBlobConst.EVENT_MESSAGE, args);
52
                 .emit(RNFetchBlobConst.EVENT_MESSAGE, args);
53
     }
53
     }
54
 
54
 
55
-    public static OkHttpClient.Builder getUnsafeOkHttpClient() {
55
+    public static OkHttpClient.Builder getUnsafeOkHttpClient(OkHttpClient client) {
56
         try {
56
         try {
57
             // Create a trust manager that does not validate certificate chains
57
             // Create a trust manager that does not validate certificate chains
58
             final TrustManager[] trustAllCerts = new TrustManager[]{
58
             final TrustManager[] trustAllCerts = new TrustManager[]{
78
             // Create an ssl socket factory with our all-trusting manager
78
             // Create an ssl socket factory with our all-trusting manager
79
             final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
79
             final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
80
 
80
 
81
-            OkHttpClient.Builder builder = new OkHttpClient.Builder();
81
+            OkHttpClient.Builder builder = client.newBuilder();
82
             builder.sslSocketFactory(sslSocketFactory);
82
             builder.sslSocketFactory(sslSocketFactory);
83
             builder.hostnameVerifier(new HostnameVerifier() {
83
             builder.hostnameVerifier(new HostnameVerifier() {
84
                 @Override
84
                 @Override

+ 0
- 66
android/src/main/java/com/RNFetchBlob/Utils/RNFBCookieJar.java 查看文件

1
-package com.RNFetchBlob.Utils;
2
-
3
-import com.facebook.react.bridge.Arguments;
4
-import com.facebook.react.bridge.ReadableMap;
5
-import com.facebook.react.bridge.WritableArray;
6
-import com.facebook.react.bridge.WritableMap;
7
-
8
-import java.util.ArrayList;
9
-import java.util.HashMap;
10
-import java.util.List;
11
-import java.util.Set;
12
-
13
-import okhttp3.Cookie;
14
-import okhttp3.CookieJar;
15
-import okhttp3.HttpUrl;
16
-
17
-/**
18
- * Created by wkh237on 2016/10/14.
19
- */
20
-
21
-
22
-
23
-public class RNFBCookieJar implements CookieJar {
24
-
25
-    static final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
26
-    private List<Cookie> cookies;
27
-
28
-    @Override
29
-    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
30
-        cookieStore.put(url.host(), cookies);
31
-    }
32
-
33
-    @Override
34
-    public List<Cookie> loadForRequest(HttpUrl url) {
35
-        List<Cookie> cookies = cookieStore.get(url.host());
36
-        return cookies != null ? cookies : new ArrayList<Cookie>();
37
-    }
38
-
39
-    public static void removeCookies(String domain) {
40
-        if(domain != null && domain.length() > 0) {
41
-            if(cookieStore.containsKey(domain))
42
-                cookieStore.remove(domain);
43
-        }
44
-        else
45
-            cookieStore.clear();
46
-    }
47
-
48
-    public static WritableMap getCookies(String host) {
49
-        Set<String> domains = cookieStore.keySet();
50
-        WritableMap cookieMap = Arguments.createMap();
51
-        if(host.length() > 0 && cookieStore.containsKey(host)) {
52
-            domains.clear();
53
-            domains.add(host);
54
-        }
55
-        // no domain specified, return all cookies
56
-        for(String key : domains) {
57
-            WritableArray cookiesInDomain = Arguments.createArray();
58
-            for(Cookie c: cookieStore.get(key)){
59
-                cookiesInDomain.pushString(c.toString());
60
-            }
61
-            cookieMap.putArray(key, cookiesInDomain);
62
-        }
63
-
64
-        return cookieMap;
65
-    }
66
-}

+ 0
- 2
index.js 查看文件

25
 import _ from 'lodash'
25
 import _ from 'lodash'
26
 import android from './android'
26
 import android from './android'
27
 import ios from './ios'
27
 import ios from './ios'
28
-import net from './net'
29
 import JSONStream from './json-stream'
28
 import JSONStream from './json-stream'
30
 const {
29
 const {
31
   RNFetchBlobSession,
30
   RNFetchBlobSession,
564
   session,
563
   session,
565
   fs,
564
   fs,
566
   wrap,
565
   wrap,
567
-  net,
568
   polyfill,
566
   polyfill,
569
   JSONStream
567
   JSONStream
570
 }
568
 }

+ 0
- 19
ios/RNFetchBlob/RNFetchBlob.m 查看文件

580
     return window.rootViewController;
580
     return window.rootViewController;
581
 }
581
 }
582
 
582
 
583
-# pragma mark - getCookies
584
-
585
-RCT_EXPORT_METHOD(getCookies:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
586
-{
587
-    resolve([RNFetchBlobNetwork getCookies:url]);
588
-}
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
-
602
 # pragma mark - check expired network events
583
 # pragma mark - check expired network events
603
 
584
 
604
 RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
585
 RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)

+ 0
- 2
ios/RNFetchBlobNetwork.h 查看文件

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;
53
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config;
52
 + (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config;
54
 + (void) enableUploadProgress:(NSString *) taskId config:(RNFetchBlobProgress *)config;
53
 + (void) enableUploadProgress:(NSString *) taskId config:(RNFetchBlobProgress *)config;
55
-+ (NSDictionary *) getCookies:(NSString *) url;
56
 
54
 
57
 
55
 
58
 
56
 

+ 0
- 83
ios/RNFetchBlobNetwork.m 查看文件

578
     }
578
     }
579
 }
579
 }
580
 
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
-
664
 + (void) cancelRequest:(NSString *)taskId
581
 + (void) cancelRequest:(NSString *)taskId
665
 {
582
 {
666
     NSURLSessionDataTask * task = [taskTable objectForKey:taskId];
583
     NSURLSessionDataTask * task = [taskTable objectForKey:taskId];

+ 0
- 36
net.js 查看文件

1
-// Copyright 2016 wkh237@github. All rights reserved.
2
-// Use of this source code is governed by a MIT-style license that can be
3
-// found in the LICENSE file.
4
-
5
-import {
6
-  NativeModules,
7
-  DeviceEventEmitter,
8
-  Platform,
9
-  NativeAppEventEmitter,
10
-} from 'react-native'
11
-
12
-const RNFetchBlob = NativeModules.RNFetchBlob
13
-
14
-/**
15
- * Get cookie according to the given url.
16
- * @param  {string} domain Domain of the cookies to be removed, remove all
17
- * @return {Promise<Array<String>>}     Cookies of a specific domain.
18
- */
19
-function getCookies(domain:string):Promise<Array<String>> {
20
-  return RNFetchBlob.getCookies(domain || '')
21
-}
22
-
23
-/**
24
- * Remove cookies for a specific domain
25
- * @param  {?string} domain Domain of the cookies to be removed, remove all
26
- * cookies when this is null.
27
- * @return {Promise<null>}
28
- */
29
-function removeCookies(domain:?string):Promise<null> {
30
-  return RNFetchBlob.removeCookies(domain || '')
31
-}
32
-
33
-export default {
34
-  getCookies,
35
-  removeCookies
36
-}