Browse Source

Add #29 Android implementation

Ben Hsieh 8 years ago
parent
commit
7edc5c8c38

+ 4
- 149
src/android/src/main/java/com/RNFetchBlob/RNFetchBlob.java View File

17
 import com.loopj.android.http.AsyncHttpClient;
17
 import com.loopj.android.http.AsyncHttpClient;
18
 import com.loopj.android.http.AsyncHttpResponseHandler;
18
 import com.loopj.android.http.AsyncHttpResponseHandler;
19
 import com.loopj.android.http.Base64;
19
 import com.loopj.android.http.Base64;
20
+import com.loopj.android.http.MySSLSocketFactory;
20
 import com.loopj.android.http.RequestParams;
21
 import com.loopj.android.http.RequestParams;
21
 
22
 
22
 import java.io.ByteArrayOutputStream;
23
 import java.io.ByteArrayOutputStream;
23
 import java.io.File;
24
 import java.io.File;
25
+import java.security.KeyStore;
24
 import java.util.HashMap;
26
 import java.util.HashMap;
25
 import java.util.Map;
27
 import java.util.Map;
26
 
28
 
156
 
158
 
157
     @ReactMethod
159
     @ReactMethod
158
     public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
160
     public void fetchBlob(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
159
-
160
-        RNFetchBlobConfig config = new RNFetchBlobConfig(options);
161
-
162
-        try {
163
-            AsyncHttpClient req = new AsyncHttpClient();
164
-
165
-            AbstractHttpEntity entity = null;
166
-
167
-            // set headers
168
-            ReadableMapKeySetIterator it = headers.keySetIterator();
169
-            while (it.hasNextKey()) {
170
-                String key = it.nextKey();
171
-                req.addHeader(key, headers.getString(key));
172
-            }
173
-
174
-            // set body for POST and PUT
175
-            if(body != null && method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put")) {
176
-
177
-                byte [] blob;
178
-                // upload from storage
179
-                if(body.startsWith(filePathPrefix)) {
180
-                    String filePath = body.substring(filePathPrefix.length());
181
-                    entity = new FileEntity(new File(filePath));
182
-                }
183
-                else {
184
-                    blob = Base64.decode(body, 0);
185
-                    entity = new ByteArrayEntity(blob);
186
-                }
187
-                entity.setContentType(headers.getString("Content-Type"));
188
-            }
189
-
190
-            AsyncHttpResponseHandler handler;
191
-
192
-            // create handler
193
-            if(config.fileCache || config.path != null) {
194
-                handler = new RNFetchBlobFileHandler(this.getReactApplicationContext(), taskId, config, callback);
195
-                // if path format invalid, throw error
196
-                if (!((RNFetchBlobFileHandler)handler).isValid) {
197
-                    callback.invoke("RNFetchBlob fetch error, configuration path `"+ config.path  +"` is not a valid path.");
198
-                    return;
199
-                }
200
-            }
201
-            else
202
-                handler = new RNFetchBlobBinaryHandler(this.getReactApplicationContext(), taskId, callback);
203
-
204
-            // send request
205
-            switch(method.toLowerCase()) {
206
-                case "get" :
207
-                    req.get(url, handler);
208
-                    break;
209
-                case "post" :
210
-                    req.post(this.getReactApplicationContext(), url, entity, "octet-stream", handler);
211
-                    break;
212
-                case "put" :
213
-                    req.put(this.getReactApplicationContext(), url, entity, "octet-stream",handler);
214
-                    break;
215
-                case "delete" :
216
-                    req.delete(url, handler);
217
-                    break;
218
-            }
219
-        } catch(Exception error) {
220
-            callback.invoke( "RNFetchBlob serialize request data failed: " + error.getMessage() + error.getCause());
221
-        }
222
-
161
+        new RNFetchBlobReq(this.getReactApplicationContext(), options, taskId, method, url, headers, body, callback).run();
223
     }
162
     }
224
 
163
 
225
     @ReactMethod
164
     @ReactMethod
226
     public void fetchBlobForm(ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
165
     public void fetchBlobForm(ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
227
-
228
-        RNFetchBlobConfig config = new RNFetchBlobConfig(options);
229
-        try {
230
-
231
-            AsyncHttpClient req = new AsyncHttpClient();
232
-
233
-            HttpEntity entity = null;
234
-
235
-            // set headers
236
-            if(headers != null) {
237
-                ReadableMapKeySetIterator it = headers.keySetIterator();
238
-                while (it.hasNextKey()) {
239
-                    String key = it.nextKey();
240
-                    req.addHeader(key, headers.getString(key));
241
-                }
242
-            }
243
-
244
-            // set body for POST and PUT
245
-            if(body != null && method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put")) {
246
-                Long tsLong = System.currentTimeMillis()/1000;
247
-                String ts = tsLong.toString();
248
-                String boundary = "RNFetchBlob".concat(ts);
249
-                MultipartEntityBuilder form = MultipartEntityBuilder.create();
250
-                form.setBoundary(boundary);
251
-                for( int i = 0; i< body.size(); i++) {
252
-                    ReadableMap map = body.getMap(i);
253
-                    String name = map.getString("name");
254
-                    if(!map.hasKey("data"))
255
-                        continue;
256
-                    String data = map.getString("data");
257
-                    // file field
258
-                    if(map.hasKey("filename")) {
259
-                        String filename = map.getString("filename");
260
-                        // upload from storage
261
-                        if(data.startsWith(filePathPrefix)) {
262
-                            File file = new File(data.substring(filePathPrefix.length()));
263
-                            form.addBinaryBody(name, file, ContentType.APPLICATION_OCTET_STREAM, filename);
264
-                        }
265
-                        // base64 embedded file content
266
-                        else {
267
-                            form.addBinaryBody(name, Base64.decode(data, 0), ContentType.APPLICATION_OCTET_STREAM, filename);
268
-                        }
269
-                    }
270
-                    // data field
271
-                    else {
272
-                        form.addTextBody(name, map.getString("data"));
273
-                    }
274
-                }
275
-                entity = form.build();
276
-                req.addHeader("Content-Type", headers.getString("Content-Type") + "; charset=utf8; boundary=" + boundary);
277
-            }
278
-
279
-            AsyncHttpResponseHandler handler;
280
-
281
-            // create handler
282
-            if(config.fileCache || config.path != null) {
283
-                handler = new RNFetchBlobFileHandler(this.getReactApplicationContext(), taskId, config, callback);
284
-                // if path format invalid, throw error
285
-                if (!((RNFetchBlobFileHandler)handler).isValid) {
286
-                    callback.invoke("RNFetchBlob fetch error, configuration path `"+ config.path  +"` is not a valid path.");
287
-                    return;
288
-                }
289
-            }
290
-            else
291
-                handler = new RNFetchBlobBinaryHandler(this.getReactApplicationContext(), taskId, callback);
292
-
293
-            // send request
294
-            switch(method.toLowerCase()) {
295
-                case "get" :
296
-                    req.get(url, handler);
297
-                    break;
298
-                case "post" :
299
-                    req.post(this.getReactApplicationContext(), url, entity, "multipart/form-data; charset=utf8", handler);
300
-                    break;
301
-                case "put" :
302
-                    req.put(this.getReactApplicationContext(), url, entity, "multipart/form-data",handler);
303
-                    break;
304
-                case "delete" :
305
-                    req.delete(url, handler);
306
-                    break;
307
-            }
308
-        } catch(Exception error) {
309
-            callback.invoke( "RNFetchBlob serialize request data failed: " + error.getMessage() + error.getCause());
310
-        }
311
-
166
+        new RNFetchBlobReq(this.getReactApplicationContext(), options, taskId, method, url, headers, body, callback).run();
312
     }
167
     }
313
 
168
 
314
 }
169
 }

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

13
     public String path;
13
     public String path;
14
     public String appendExt;
14
     public String appendExt;
15
     public ReadableMap addAndroidDownloads;
15
     public ReadableMap addAndroidDownloads;
16
+    public Boolean trusty;
16
 
17
 
17
     RNFetchBlobConfig(ReadableMap options) {
18
     RNFetchBlobConfig(ReadableMap options) {
18
         if(options == null)
19
         if(options == null)
20
         this.fileCache = options.hasKey("fileCache") ? options.getBoolean("fileCache") : false;
21
         this.fileCache = options.hasKey("fileCache") ? options.getBoolean("fileCache") : false;
21
         this.path = options.hasKey("path") ? options.getString("path") : null;
22
         this.path = options.hasKey("path") ? options.getString("path") : null;
22
         this.appendExt = options.hasKey("appendExt") ? options.getString("appendExt") : "";
23
         this.appendExt = options.hasKey("appendExt") ? options.getString("appendExt") : "";
24
+        this.trusty = options.hasKey("trusty") ? options.getBoolean("trusty") : false;
23
         if(options.hasKey("addAndroidDownloads")) {
25
         if(options.hasKey("addAndroidDownloads")) {
24
             this.addAndroidDownloads = options.getMap("addAndroidDownloads");
26
             this.addAndroidDownloads = options.getMap("addAndroidDownloads");
25
         }
27
         }

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

19
 import java.util.List;
19
 import java.util.List;
20
 
20
 
21
 /**
21
 /**
22
- * Created by xeiyan on 2016/4/29.
22
+ * Created by wkh237 on 2016/4/29.
23
  */
23
  */
24
 public class RNFetchBlobPackage implements ReactPackage {
24
 public class RNFetchBlobPackage implements ReactPackage {
25
 
25
 

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

1
+package com.RNFetchBlob;
2
+
3
+import com.facebook.react.bridge.Callback;
4
+import com.facebook.react.bridge.ReactApplicationContext;
5
+import com.facebook.react.bridge.ReadableArray;
6
+import com.facebook.react.bridge.ReadableMap;
7
+import com.facebook.react.bridge.ReadableMapKeySetIterator;
8
+import com.loopj.android.http.AsyncHttpClient;
9
+import com.loopj.android.http.AsyncHttpResponseHandler;
10
+import com.loopj.android.http.Base64;
11
+import com.loopj.android.http.MySSLSocketFactory;
12
+
13
+import java.io.File;
14
+import java.nio.charset.Charset;
15
+import java.security.KeyStore;
16
+
17
+import cz.msebera.android.httpclient.HttpEntity;
18
+import cz.msebera.android.httpclient.entity.AbstractHttpEntity;
19
+import cz.msebera.android.httpclient.entity.ByteArrayEntity;
20
+import cz.msebera.android.httpclient.entity.ContentType;
21
+import cz.msebera.android.httpclient.entity.FileEntity;
22
+import cz.msebera.android.httpclient.entity.mime.MultipartEntityBuilder;
23
+
24
+/**
25
+ * Created by wkh237 on 2016/6/21.
26
+ */
27
+public class RNFetchBlobReq implements Runnable{
28
+
29
+    final String filePathPrefix = "RNFetchBlob-file://";
30
+    ReactApplicationContext ctx;
31
+    RNFetchBlobConfig options;
32
+    String taskId;
33
+    String method;
34
+    String url;
35
+    String boundary;
36
+    ReadableMap headers;
37
+    Callback callback;
38
+    HttpEntity entity;
39
+    AsyncHttpClient req;
40
+    String type;
41
+
42
+    public RNFetchBlobReq(ReactApplicationContext ctx, ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
43
+        this.ctx = ctx;
44
+        this.method = method;
45
+        this.options= new RNFetchBlobConfig(options);
46
+        this.taskId = taskId;
47
+        this.url = url;
48
+        this.headers = headers;
49
+        this.callback = callback;
50
+        this.req = new AsyncHttpClient();
51
+        if(body != null) {
52
+            type = "octet";
53
+            buildEntity(body);
54
+        }
55
+    }
56
+
57
+    public RNFetchBlobReq(ReactApplicationContext ctx, ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
58
+        this.ctx = ctx;
59
+        this.method = method;
60
+        this.options= new RNFetchBlobConfig(options);
61
+        this.taskId = taskId;
62
+        this.url = url;
63
+        this.headers = headers;
64
+        this.callback = callback;
65
+        this.req = new AsyncHttpClient();
66
+        if(body != null) {
67
+            type = "form";
68
+            buildFormEntity(body);
69
+        }
70
+    }
71
+
72
+    @Override
73
+    public void run() {
74
+
75
+        try {
76
+
77
+//            AsyncHttpClient req = new AsyncHttpClient();
78
+
79
+            // use trusty SSL socket
80
+            if(this.options.trusty) {
81
+                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
82
+                trustStore.load(null, null);
83
+                MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
84
+                sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
85
+                req.setSSLSocketFactory(sf);
86
+            }
87
+
88
+            // set headers
89
+            if(headers != null) {
90
+                ReadableMapKeySetIterator it = headers.keySetIterator();
91
+                while (it.hasNextKey()) {
92
+                    String key = it.nextKey();
93
+                    req.addHeader(key, headers.getString(key));
94
+                }
95
+            }
96
+
97
+            if(type != null)
98
+            {
99
+                if(type == "octet")
100
+                    req.addHeader("Content-Type", "application/octet-stream");
101
+                else if(type == "form")
102
+                    req.addHeader("Content-Type", "multipart/form-data; charset=utf8; boundary="+boundary);
103
+            }
104
+
105
+            AsyncHttpResponseHandler handler;
106
+
107
+            // create handler
108
+            if(options.fileCache || options.path != null) {
109
+                handler = new RNFetchBlobFileHandler(ctx, taskId, options, callback);
110
+                // if path format invalid, throw error
111
+                if (!((RNFetchBlobFileHandler)handler).isValid) {
112
+                    callback.invoke("RNFetchBlob fetch error, configuration path `"+ options.path  +"` is not a valid path.");
113
+                    return;
114
+                }
115
+            }
116
+            else
117
+                handler = new RNFetchBlobBinaryHandler(this.ctx, taskId, callback);
118
+
119
+            // send request
120
+            switch(method.toLowerCase()) {
121
+                case "get" :
122
+                    req.get(url, handler);
123
+                    break;
124
+                case "post" :
125
+                    if(this.type == null || this.type.equalsIgnoreCase("octet"))
126
+                        req.post(ctx, url, entity, "application/octet-stream", handler);
127
+                    else
128
+                        req.post(ctx, url, entity, "multipart/form-data", handler);
129
+                    break;
130
+                case "put" :
131
+                    if(this.type == null || this.type.equalsIgnoreCase("octet"))
132
+                        req.post(ctx, url, entity, "application/octet-stream", handler);
133
+                    else
134
+                        req.post(ctx, url, entity, "multipart/form-data", handler);
135
+                    break;
136
+                case "delete" :
137
+                    req.delete(url, handler);
138
+                    break;
139
+            }
140
+        } catch(Exception error) {
141
+            callback.invoke( "RNFetchBlob serialize request data failed: " + error.getMessage() + error.getCause());
142
+        }
143
+    }
144
+
145
+    /**
146
+     * Build Mutipart body
147
+     * @param body  Body in array format
148
+     */
149
+    void buildFormEntity(ReadableArray body) {
150
+        if(body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
151
+            Long tsLong = System.currentTimeMillis()/1000;
152
+            String ts = tsLong.toString();
153
+            boundary = "RNFetchBlob".concat(ts);
154
+            MultipartEntityBuilder form = MultipartEntityBuilder.create();
155
+            form.setBoundary(boundary);
156
+            for( int i = 0; i< body.size(); i++) {
157
+                ReadableMap map = body.getMap(i);
158
+                String name = map.getString("name");
159
+                if(!map.hasKey("data"))
160
+                    continue;
161
+                String data = map.getString("data");
162
+                // file field
163
+                if(map.hasKey("filename")) {
164
+                    String filename = map.getString("filename");
165
+                    // upload from storage
166
+                    if(data.startsWith(filePathPrefix)) {
167
+                        File file = new File(data.substring(filePathPrefix.length()));
168
+                        form.addBinaryBody(name, file, ContentType.APPLICATION_OCTET_STREAM, filename);
169
+                    }
170
+                    // base64 embedded file content
171
+                    else {
172
+                        form.addBinaryBody(name, Base64.decode(data, 0), ContentType.APPLICATION_OCTET_STREAM, filename);
173
+                    }
174
+                }
175
+                // data field
176
+                else {
177
+                    form.addTextBody(name, map.getString("data"));
178
+                }
179
+            }
180
+            entity = form.build();
181
+        }
182
+    }
183
+
184
+    /**
185
+     * Build Octet-Stream body
186
+     * @param body  Body in string format
187
+     */
188
+    void buildEntity(String body) {
189
+        // set body for POST and PUT
190
+        if(body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
191
+
192
+            byte [] blob;
193
+            // upload from storage
194
+            if(body.startsWith(filePathPrefix)) {
195
+                String filePath = body.substring(filePathPrefix.length());
196
+                entity = new FileEntity(new File(filePath));
197
+            }
198
+            else {
199
+                blob = Base64.decode(body, 0);
200
+                entity = new ByteArrayEntity(blob);
201
+            }
202
+        }
203
+
204
+    }
205
+}