|
@@ -8,114 +8,102 @@ import android.content.IntentFilter;
|
8
|
8
|
import android.database.Cursor;
|
9
|
9
|
import android.net.Uri;
|
10
|
10
|
|
|
11
|
+import com.RNFetchBlob.Request.FormPartBody;
|
|
12
|
+import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
|
|
13
|
+import com.RNFetchBlob.Response.RNFetchBlobFileResp;
|
11
|
14
|
import com.facebook.react.bridge.Callback;
|
12
|
15
|
import com.facebook.react.bridge.ReactApplicationContext;
|
13
|
16
|
import com.facebook.react.bridge.ReadableArray;
|
14
|
17
|
import com.facebook.react.bridge.ReadableMap;
|
15
|
18
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
16
|
|
-import com.loopj.android.http.AsyncHttpClient;
|
17
|
|
-import com.loopj.android.http.AsyncHttpResponseHandler;
|
18
|
19
|
import com.loopj.android.http.Base64;
|
19
|
|
-import com.loopj.android.http.MySSLSocketFactory;
|
20
|
20
|
|
|
21
|
+import java.io.ByteArrayInputStream;
|
21
|
22
|
import java.io.File;
|
|
23
|
+import java.io.FileInputStream;
|
|
24
|
+import java.io.FileNotFoundException;
|
22
|
25
|
import java.io.IOException;
|
23
|
26
|
import java.io.InputStream;
|
24
|
|
-import java.security.KeyStore;
|
25
|
|
-import java.security.MessageDigest;
|
26
|
27
|
|
27
|
|
-import cz.msebera.android.httpclient.HttpEntity;
|
28
|
|
-import cz.msebera.android.httpclient.entity.ByteArrayEntity;
|
29
|
|
-import cz.msebera.android.httpclient.entity.ContentType;
|
30
|
|
-import cz.msebera.android.httpclient.entity.FileEntity;
|
31
|
|
-import cz.msebera.android.httpclient.entity.mime.MultipartEntityBuilder;
|
|
28
|
+import okhttp3.Call;
|
|
29
|
+import okhttp3.Interceptor;
|
|
30
|
+import okhttp3.MediaType;
|
|
31
|
+import okhttp3.MultipartBody;
|
|
32
|
+import okhttp3.OkHttpClient;
|
|
33
|
+import okhttp3.Request;
|
|
34
|
+import okhttp3.RequestBody;
|
|
35
|
+import okhttp3.Response;
|
32
|
36
|
|
33
|
37
|
/**
|
34
|
38
|
* Created by wkh237 on 2016/6/21.
|
35
|
39
|
*/
|
36
|
40
|
public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
37
|
41
|
|
38
|
|
- final String filePathPrefix = "RNFetchBlob-file://";
|
|
42
|
+ enum RequestType {
|
|
43
|
+ Form,
|
|
44
|
+ SingleFile,
|
|
45
|
+ Others
|
|
46
|
+ };
|
|
47
|
+
|
|
48
|
+ enum ResponseType {
|
|
49
|
+ MemoryCache,
|
|
50
|
+ FileCache
|
|
51
|
+ };
|
|
52
|
+
|
|
53
|
+ MediaType contentType = RNFetchBlobConst.MIME_OCTET;
|
39
|
54
|
ReactApplicationContext ctx;
|
40
|
55
|
RNFetchBlobConfig options;
|
41
|
56
|
String taskId;
|
42
|
57
|
String method;
|
43
|
58
|
String url;
|
44
|
|
- String boundary;
|
|
59
|
+ String rawRequestBody;
|
|
60
|
+ String destPath;
|
|
61
|
+ ReadableArray rawRequestBodyArray;
|
45
|
62
|
ReadableMap headers;
|
46
|
63
|
Callback callback;
|
47
|
|
- HttpEntity entity;
|
|
64
|
+ long contentLength;
|
48
|
65
|
long downloadManagerId;
|
49
|
|
- AsyncHttpClient req;
|
50
|
|
- String type;
|
|
66
|
+ RequestType requestType;
|
|
67
|
+ ResponseType responseType;
|
51
|
68
|
|
52
|
|
- public RNFetchBlobReq(ReactApplicationContext ctx, ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, final Callback callback) {
|
53
|
|
- this.ctx = ctx;
|
|
69
|
+ public RNFetchBlobReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, final Callback callback) {
|
54
|
70
|
this.method = method;
|
55
|
|
- this.options= new RNFetchBlobConfig(options);
|
|
71
|
+ this.options = new RNFetchBlobConfig(options);
|
56
|
72
|
this.taskId = taskId;
|
57
|
73
|
this.url = url;
|
58
|
74
|
this.headers = headers;
|
59
|
75
|
this.callback = callback;
|
60
|
|
- this.req = new AsyncHttpClient();
|
61
|
|
- if(body != null) {
|
62
|
|
- type = "octet";
|
63
|
|
- buildEntity(body);
|
64
|
|
- }
|
65
|
|
- }
|
66
|
|
-
|
67
|
|
- public RNFetchBlobReq(ReactApplicationContext ctx, ReadableMap options, String taskId, String method, String url, ReadableMap headers, ReadableArray body, final Callback callback) {
|
68
|
|
- this.ctx = ctx;
|
69
|
|
- this.method = method;
|
70
|
|
- this.options= new RNFetchBlobConfig(options);
|
71
|
|
- this.taskId = taskId;
|
72
|
|
- this.url = url;
|
73
|
|
- this.headers = headers;
|
74
|
|
- this.callback = callback;
|
75
|
|
- this.req = new AsyncHttpClient();
|
76
|
|
- if(body != null) {
|
77
|
|
- type = "form";
|
78
|
|
- buildFormEntity(body);
|
79
|
|
- }
|
80
|
|
- }
|
81
|
|
-
|
82
|
|
- public static String getMD5(String input) {
|
83
|
|
- String result = null;
|
84
|
|
-
|
85
|
|
- try {
|
86
|
|
- MessageDigest md = MessageDigest.getInstance("MD5");
|
87
|
|
- md.update(input.getBytes());
|
88
|
|
- byte[] digest = md.digest();
|
89
|
|
-
|
90
|
|
- StringBuffer sb = new StringBuffer();
|
91
|
|
-
|
92
|
|
- for (byte b : digest) {
|
93
|
|
- sb.append(String.format("%02x", b & 0xff));
|
94
|
|
- }
|
95
|
|
-
|
96
|
|
- result = sb.toString();
|
97
|
|
- } catch(Exception ex) {
|
98
|
|
- ex.printStackTrace();
|
99
|
|
- }
|
100
|
|
-
|
101
|
|
- return result;
|
|
76
|
+ this.rawRequestBody = body;
|
|
77
|
+ this.rawRequestBodyArray = arrayBody;
|
|
78
|
+
|
|
79
|
+ if(this.options.fileCache != null || this.options.path != null)
|
|
80
|
+ responseType = ResponseType.FileCache;
|
|
81
|
+ else
|
|
82
|
+ responseType = ResponseType.MemoryCache;
|
|
83
|
+
|
|
84
|
+ if (body != null)
|
|
85
|
+ requestType = RequestType.SingleFile;
|
|
86
|
+ else if (arrayBody != null)
|
|
87
|
+ requestType = RequestType.Form;
|
|
88
|
+ else
|
|
89
|
+ requestType = RequestType.Others;
|
102
|
90
|
}
|
103
|
91
|
|
104
|
92
|
@Override
|
105
|
93
|
public void run() {
|
106
|
94
|
|
107
|
95
|
// use download manager instead of default HTTP implementation
|
108
|
|
- if(options.addAndroidDownloads != null && options.addAndroidDownloads.hasKey("useDownloadManager")) {
|
|
96
|
+ if (options.addAndroidDownloads != null && options.addAndroidDownloads.hasKey("useDownloadManager")) {
|
109
|
97
|
|
110
|
|
- if(options.addAndroidDownloads.getBoolean("useDownloadManager")) {
|
|
98
|
+ if (options.addAndroidDownloads.getBoolean("useDownloadManager")) {
|
111
|
99
|
Uri uri = Uri.parse(url);
|
112
|
100
|
DownloadManager.Request req = new DownloadManager.Request(uri);
|
113
|
101
|
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
114
|
102
|
|
115
|
|
- if(options.addAndroidDownloads.hasKey("title")) {
|
|
103
|
+ if (options.addAndroidDownloads.hasKey("title")) {
|
116
|
104
|
req.setTitle(options.addAndroidDownloads.getString("title"));
|
117
|
105
|
}
|
118
|
|
- if(options.addAndroidDownloads.hasKey("description")) {
|
|
106
|
+ if (options.addAndroidDownloads.hasKey("description")) {
|
119
|
107
|
req.setDescription(options.addAndroidDownloads.getString("description"));
|
120
|
108
|
}
|
121
|
109
|
// set headers
|
|
@@ -132,186 +120,244 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
132
|
120
|
|
133
|
121
|
}
|
134
|
122
|
|
|
123
|
+ // find cached result if `key` property exists
|
135
|
124
|
String cacheKey = this.taskId;
|
136
|
125
|
if (this.options.key != null) {
|
137
|
|
- cacheKey = RNFetchBlobReq.getMD5(this.options.key);
|
|
126
|
+ cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
|
138
|
127
|
if (cacheKey == null) {
|
139
|
128
|
cacheKey = this.taskId;
|
140
|
129
|
}
|
141
|
130
|
|
142
|
|
- File file = new File(RNFetchBlobFileHandler.getFilePath(ctx, taskId, cacheKey, this.options));
|
|
131
|
+ File file = new File(RNFetchBlobFS.getTmpPath(ctx, cacheKey));
|
143
|
132
|
if (file.exists()) {
|
144
|
|
- callback.invoke(null, file.getAbsolutePath());
|
145
|
|
- return;
|
|
133
|
+ callback.invoke(null, file.getAbsolutePath());
|
|
134
|
+ return;
|
146
|
135
|
}
|
147
|
136
|
}
|
148
|
137
|
|
149
|
|
- try {
|
150
|
|
-
|
151
|
|
- req = new AsyncHttpClient();
|
|
138
|
+ if(this.options.path != null)
|
|
139
|
+ destPath = this.options.path;
|
|
140
|
+ else if(this.options.fileCache)
|
|
141
|
+ destPath = RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey);
|
152
|
142
|
|
153
|
|
- req.setLoggingEnabled(false);
|
|
143
|
+ OkHttpClient client;
|
|
144
|
+ try {
|
154
|
145
|
|
155
|
146
|
// use trusty SSL socket
|
156
|
|
- if(this.options.trusty) {
|
157
|
|
- KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
158
|
|
- trustStore.load(null, null);
|
159
|
|
- MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
|
160
|
|
- sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
161
|
|
- req.setSSLSocketFactory(sf);
|
|
147
|
+ if (this.options.trusty) {
|
|
148
|
+ client = RNFetchBlobUtils.getUnsafeOkHttpClient();
|
|
149
|
+ } else {
|
|
150
|
+ client = new OkHttpClient();
|
162
|
151
|
}
|
163
|
152
|
|
|
153
|
+ final Request.Builder builder = new Request.Builder();
|
|
154
|
+
|
164
|
155
|
// set headers
|
165
|
|
- if(headers != null) {
|
|
156
|
+ if (headers != null) {
|
166
|
157
|
ReadableMapKeySetIterator it = headers.keySetIterator();
|
167
|
158
|
while (it.hasNextKey()) {
|
168
|
159
|
String key = it.nextKey();
|
169
|
|
- req.addHeader(key, headers.getString(key));
|
|
160
|
+ builder.addHeader(key, headers.getString(key));
|
170
|
161
|
}
|
171
|
162
|
}
|
172
|
163
|
|
173
|
|
- if(type != null)
|
174
|
|
- {
|
175
|
|
- if(type == "octet")
|
176
|
|
- req.addHeader("Content-Type", "application/octet-stream");
|
177
|
|
- else if(type == "form")
|
178
|
|
- req.addHeader("Content-Type", "multipart/form-data; charset=utf8; boundary="+boundary);
|
|
164
|
+ // set request body
|
|
165
|
+ switch (requestType) {
|
|
166
|
+ case SingleFile:
|
|
167
|
+ builder.method(method, new RNFetchBlobBody(
|
|
168
|
+ taskId,
|
|
169
|
+ RequestType.SingleFile,
|
|
170
|
+ null,
|
|
171
|
+ buildOctetBody(rawRequestBody),
|
|
172
|
+ contentLength
|
|
173
|
+ ));
|
|
174
|
+ break;
|
|
175
|
+ case Form:
|
|
176
|
+ builder.method(method, new RNFetchBlobBody(
|
|
177
|
+ taskId,
|
|
178
|
+ RequestType.Form,
|
|
179
|
+ buildFormBody(rawRequestBodyArray),
|
|
180
|
+ null,
|
|
181
|
+ contentLength
|
|
182
|
+ ));
|
|
183
|
+ case Others:
|
|
184
|
+ builder.method(method, new RNFetchBlobBody(
|
|
185
|
+ taskId,
|
|
186
|
+ RequestType.Others,
|
|
187
|
+ buildRawBody(rawRequestBody),
|
|
188
|
+ null,
|
|
189
|
+ contentLength
|
|
190
|
+ ));
|
|
191
|
+ break;
|
179
|
192
|
}
|
180
|
193
|
|
181
|
|
- AsyncHttpResponseHandler handler;
|
|
194
|
+ final Request req = builder.build();
|
|
195
|
+
|
|
196
|
+ // create response handler
|
|
197
|
+ client.networkInterceptors().add(new Interceptor() {
|
|
198
|
+ @Override
|
|
199
|
+ public Response intercept(Chain chain) throws IOException {
|
|
200
|
+ Response originalResponse = chain.proceed(req);
|
|
201
|
+ RNFetchBlobDefaultResp exetneded;
|
|
202
|
+ switch (responseType) {
|
|
203
|
+ case MemoryCache:
|
|
204
|
+ exetneded = new RNFetchBlobDefaultResp(
|
|
205
|
+ RNFetchBlob.RCTContext,
|
|
206
|
+ taskId,
|
|
207
|
+ originalResponse.body());
|
|
208
|
+ break;
|
|
209
|
+ case FileCache:
|
|
210
|
+ exetneded = new RNFetchBlobFileResp(
|
|
211
|
+ RNFetchBlob.RCTContext,
|
|
212
|
+ taskId,
|
|
213
|
+ originalResponse.body(),
|
|
214
|
+ destPath);
|
|
215
|
+ break;
|
|
216
|
+ default:
|
|
217
|
+ exetneded = new RNFetchBlobDefaultResp(
|
|
218
|
+ RNFetchBlob.RCTContext,
|
|
219
|
+ taskId,
|
|
220
|
+ originalResponse.body());
|
|
221
|
+ break;
|
|
222
|
+ }
|
|
223
|
+ return originalResponse.newBuilder().body(exetneded).build();
|
|
224
|
+ }
|
|
225
|
+ });
|
182
|
226
|
|
183
|
|
- // create handler
|
184
|
|
- if(options.fileCache || options.path != null) {
|
185
|
|
- handler = new RNFetchBlobFileHandler(ctx, taskId, cacheKey, options, callback);
|
186
|
|
- // if path format invalid, throw error
|
187
|
|
- if (!((RNFetchBlobFileHandler)handler).isValid) {
|
188
|
|
- callback.invoke("RNFetchBlob fetch error, configuration path `"+ options.path +"` is not a valid path.");
|
189
|
|
- return;
|
|
227
|
+ client.newCall(req).enqueue(new okhttp3.Callback() {
|
|
228
|
+ @Override
|
|
229
|
+ public void onFailure(Call call, IOException e) {
|
|
230
|
+ callback.invoke(e.getLocalizedMessage(), null);
|
190
|
231
|
}
|
191
|
|
- }
|
192
|
|
- else
|
193
|
|
- handler = new RNFetchBlobBinaryHandler(this.ctx, taskId, callback);
|
194
|
232
|
|
195
|
|
- // send request
|
196
|
|
- switch(method.toLowerCase()) {
|
197
|
|
- case "get" :
|
198
|
|
- req.get(url, handler);
|
199
|
|
- break;
|
200
|
|
- case "post" :
|
201
|
|
- if(this.type == null || this.type.equalsIgnoreCase("octet"))
|
202
|
|
- req.post(ctx, url, entity, "application/octet-stream", handler);
|
203
|
|
- else
|
204
|
|
- req.post(ctx, url, entity, "multipart/form-data", handler);
|
205
|
|
- break;
|
206
|
|
- case "put" :
|
207
|
|
- if(this.type == null || this.type.equalsIgnoreCase("octet"))
|
208
|
|
- req.put(ctx, url, entity, "application/octet-stream", handler);
|
209
|
|
- else
|
210
|
|
- req.put(ctx, url, entity, "multipart/form-data", handler);
|
211
|
|
- break;
|
212
|
|
- case "delete" :
|
213
|
|
- req.delete(url, handler);
|
214
|
|
- break;
|
215
|
|
- }
|
216
|
|
- } catch(Exception error) {
|
217
|
|
- callback.invoke( "RNFetchBlob serialize request data failed: " + error.getMessage() + error.getCause());
|
|
233
|
+ @Override
|
|
234
|
+ public void onResponse(Call call, Response response) throws IOException {
|
|
235
|
+ ReadableMap notifyConfig = options.addAndroidDownloads;
|
|
236
|
+ // Download manager settings
|
|
237
|
+ if(notifyConfig != null ) {
|
|
238
|
+ String title = "", desc = "", mime = "text/plain";
|
|
239
|
+ boolean scannable = false, notification = false;
|
|
240
|
+ if(notifyConfig.hasKey("title"))
|
|
241
|
+ title = options.addAndroidDownloads.getString("title");
|
|
242
|
+ if(notifyConfig.hasKey("description"))
|
|
243
|
+ desc = notifyConfig.getString("description");
|
|
244
|
+ if(notifyConfig.hasKey("mime"))
|
|
245
|
+ mime = notifyConfig.getString("mime");
|
|
246
|
+ if(notifyConfig.hasKey("mediaScannable"))
|
|
247
|
+ scannable = notifyConfig.getBoolean("mediaScannable");
|
|
248
|
+ if(notifyConfig.hasKey("notification"))
|
|
249
|
+ notification = notifyConfig.getBoolean("notification");
|
|
250
|
+ DownloadManager dm = (DownloadManager)RNFetchBlob.RCTContext.getSystemService(RNFetchBlob.RCTContext.DOWNLOAD_SERVICE);
|
|
251
|
+ dm.addCompletedDownload(title, desc, scannable, mime, destPath, contentLength, notification);
|
|
252
|
+ }
|
|
253
|
+ done(response);
|
|
254
|
+ }
|
|
255
|
+ });
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+ } catch (Exception error) {
|
|
259
|
+ callback.invoke("RNFetchBlob request error: " + error.getMessage() + error.getCause());
|
218
|
260
|
}
|
219
|
261
|
}
|
220
|
262
|
|
221
|
263
|
/**
|
222
|
|
- * Build Mutipart body
|
223
|
|
- * @param body Body in array format
|
|
264
|
+ * Send response data back to javascript context.
|
|
265
|
+ * @param resp OkHttp response object
|
224
|
266
|
*/
|
225
|
|
- void buildFormEntity(ReadableArray body) {
|
226
|
|
- if(body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
|
227
|
|
- Long tsLong = System.currentTimeMillis()/1000;
|
228
|
|
- String ts = tsLong.toString();
|
229
|
|
- boundary = "RNFetchBlob".concat(ts);
|
230
|
|
- MultipartEntityBuilder form = MultipartEntityBuilder.create();
|
231
|
|
- form.setBoundary(boundary);
|
232
|
|
- for( int i = 0; i< body.size(); i++) {
|
233
|
|
- ReadableMap map = body.getMap(i);
|
234
|
|
- String name = map.getString("name");
|
235
|
|
- if(!map.hasKey("data"))
|
236
|
|
- continue;
|
237
|
|
- String data = map.getString("data");
|
238
|
|
- // file field
|
239
|
|
- if(map.hasKey("filename")) {
|
240
|
|
- String mime = map.hasKey("type") ? map.getString("type") : ContentType.APPLICATION_OCTET_STREAM.getMimeType();
|
241
|
|
- String filename = map.getString("filename");
|
242
|
|
- // upload from storage
|
243
|
|
- if(data.startsWith(filePathPrefix)) {
|
244
|
|
- String orgPath = data.substring(filePathPrefix.length());
|
245
|
|
- orgPath = RNFetchBlobFS.normalizePath(orgPath);
|
246
|
|
- // path starts with content://
|
247
|
|
- if(RNFetchBlobFS.isAsset(orgPath)) {
|
248
|
|
- try {
|
249
|
|
- String assetName = orgPath.replace(RNFetchBlobFS.assetPrefix, "");
|
250
|
|
- InputStream in = RNFetchBlob.RCTContext.getAssets().open(assetName);
|
251
|
|
- long length = RNFetchBlob.RCTContext.getAssets().openFd(assetName).getLength();
|
252
|
|
- byte [] bytes = new byte[(int) length];
|
253
|
|
- in.read(bytes, 0, (int) length);
|
254
|
|
- in.close();
|
255
|
|
- form.addBinaryBody(name, bytes, ContentType.create(mime), filename);
|
256
|
|
- } catch (IOException e) {
|
257
|
|
-// e.printStackTrace();
|
258
|
|
- }
|
259
|
|
- }
|
260
|
|
- else {
|
261
|
|
- File file = new File(RNFetchBlobFS.normalizePath(orgPath));
|
262
|
|
- form.addBinaryBody(name, file, ContentType.create(mime), filename);
|
263
|
|
- }
|
264
|
|
- }
|
265
|
|
- // base64 embedded file content
|
266
|
|
- else {
|
267
|
|
- form.addBinaryBody(name, Base64.decode(data, 0), ContentType.create(mime), filename);
|
268
|
|
- }
|
|
267
|
+ private void done(Response resp) {
|
|
268
|
+ switch (responseType) {
|
|
269
|
+ case MemoryCache:
|
|
270
|
+ try {
|
|
271
|
+ callback.invoke(null, android.util.Base64.encode(resp.body().bytes(), 0));
|
|
272
|
+ } catch (IOException e) {
|
|
273
|
+ callback.invoke("RNFetchBlob failed to encode response data to BASE64 string.", null);
|
269
|
274
|
}
|
270
|
|
- // data field
|
271
|
|
- else {
|
272
|
|
- form.addTextBody(name, map.getString("data"));
|
|
275
|
+ break;
|
|
276
|
+ case FileCache:
|
|
277
|
+ callback.invoke(null, destPath);
|
|
278
|
+ break;
|
|
279
|
+ default:
|
|
280
|
+ try {
|
|
281
|
+ callback.invoke(null, new String(resp.body().bytes(), "UTF-8"));
|
|
282
|
+ } catch (IOException e) {
|
|
283
|
+ callback.invoke("RNFetchBlob failed to encode response data to UTF8 string.", null);
|
273
|
284
|
}
|
|
285
|
+ break;
|
|
286
|
+ }
|
|
287
|
+ }
|
|
288
|
+
|
|
289
|
+ /**
|
|
290
|
+ * Build request body by given string
|
|
291
|
+ * @param body Content of request body in UTF8 string format.
|
|
292
|
+ * @return
|
|
293
|
+ */
|
|
294
|
+ RequestBody buildRawBody(String body) {
|
|
295
|
+ if(body != null) {
|
|
296
|
+ this.contentType = MediaType.parse(options.mime);
|
|
297
|
+ }
|
|
298
|
+ return RequestBody.create(this.contentType, body);
|
|
299
|
+ }
|
|
300
|
+
|
|
301
|
+ /**
|
|
302
|
+ * When request body is a multipart form data, build a MultipartBody object.
|
|
303
|
+ * @param body Body in array format
|
|
304
|
+ * @return
|
|
305
|
+ */
|
|
306
|
+ MultipartBody buildFormBody(ReadableArray body) {
|
|
307
|
+ if (body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
|
|
308
|
+ this.contentType = RNFetchBlobConst.MIME_MULTIPART;
|
|
309
|
+ MultipartBody.Builder formBuilder = new MultipartBody.Builder();
|
|
310
|
+ formBuilder.setType(MultipartBody.FORM);
|
|
311
|
+
|
|
312
|
+ for (int i = 0; i < body.size(); i++) {
|
|
313
|
+ ReadableMap map = body.getMap(i);
|
|
314
|
+ FormPartBody fieldData = new FormPartBody(RNFetchBlob.RCTContext, map);
|
|
315
|
+ if(fieldData.filename == null)
|
|
316
|
+ formBuilder.addFormDataPart(fieldData.fieldName, fieldData.stringBody);
|
|
317
|
+ else
|
|
318
|
+ formBuilder.addFormDataPart(fieldData.fieldName, fieldData.filename, fieldData.partBody);
|
274
|
319
|
}
|
275
|
|
- entity = form.build();
|
|
320
|
+ return formBuilder.build();
|
276
|
321
|
}
|
|
322
|
+ return null;
|
277
|
323
|
}
|
278
|
324
|
|
279
|
325
|
/**
|
280
|
|
- * Build Octet-Stream body
|
281
|
|
- * @param body Body in string format
|
|
326
|
+ * Get InputStream of request body when request body contains a single file.
|
|
327
|
+ *
|
|
328
|
+ * @param body Body in string format
|
|
329
|
+ * @return InputStream When there's no request body, returns null
|
282
|
330
|
*/
|
283
|
|
- void buildEntity(String body) {
|
|
331
|
+ InputStream buildOctetBody(String body) {
|
284
|
332
|
// set body for POST and PUT
|
285
|
|
- if(body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
|
286
|
|
-
|
287
|
|
- byte [] blob;
|
|
333
|
+ if (body != null && (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put"))) {
|
|
334
|
+ this.contentType = RNFetchBlobConst.MIME_OCTET;
|
|
335
|
+ byte[] blob;
|
288
|
336
|
// upload from storage
|
289
|
|
- if(body.startsWith(filePathPrefix)) {
|
290
|
|
- String orgPath = body.substring(filePathPrefix.length());
|
|
337
|
+ if (body.startsWith(RNFetchBlobConst.FILE_PREFIX)) {
|
|
338
|
+ String orgPath = body.substring(RNFetchBlobConst.FILE_PREFIX.length());
|
291
|
339
|
orgPath = RNFetchBlobFS.normalizePath(orgPath);
|
292
|
340
|
// handle
|
293
|
|
- if(RNFetchBlobFS.isAsset(orgPath)) {
|
|
341
|
+ if (RNFetchBlobFS.isAsset(orgPath)) {
|
294
|
342
|
try {
|
295
|
|
- String assetName = orgPath.replace(RNFetchBlobFS.assetPrefix, "");
|
296
|
|
- InputStream in = RNFetchBlob.RCTContext.getAssets().open(assetName);
|
297
|
|
- long length = 0;
|
298
|
|
- length = RNFetchBlob.RCTContext.getAssets().openFd(assetName).getLength();
|
299
|
|
- byte [] bytes = new byte[(int) length];
|
300
|
|
- in.read(bytes, 0, (int) length);
|
301
|
|
- in.close();
|
302
|
|
- entity = new ByteArrayEntity(bytes);
|
|
343
|
+ String assetName = orgPath.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, "");
|
|
344
|
+ return RNFetchBlob.RCTContext.getAssets().open(assetName);
|
303
|
345
|
} catch (IOException e) {
|
304
|
346
|
// e.printStackTrace();
|
305
|
347
|
}
|
|
348
|
+ } else {
|
|
349
|
+ File f = new File(RNFetchBlobFS.normalizePath(orgPath));
|
|
350
|
+ try {
|
|
351
|
+ return new FileInputStream(f);
|
|
352
|
+ } catch (FileNotFoundException e) {
|
|
353
|
+ callback.invoke(e.getLocalizedMessage(), null);
|
|
354
|
+ }
|
306
|
355
|
}
|
307
|
|
- else
|
308
|
|
- entity = new FileEntity(new File(RNFetchBlobFS.normalizePath(orgPath)));
|
309
|
|
- }
|
310
|
|
- else {
|
311
|
|
- blob = Base64.decode(body, 0);
|
312
|
|
- entity = new ByteArrayEntity(blob);
|
|
356
|
+ } else {
|
|
357
|
+ return new ByteArrayInputStream(Base64.decode(body, 0));
|
313
|
358
|
}
|
314
|
359
|
}
|
|
360
|
+ return null;
|
315
|
361
|
|
316
|
362
|
}
|
317
|
363
|
|
|
@@ -320,7 +366,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
320
|
366
|
String action = intent.getAction();
|
321
|
367
|
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
|
322
|
368
|
long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
|
323
|
|
- if(id == this.downloadManagerId) {
|
|
369
|
+ if (id == this.downloadManagerId) {
|
324
|
370
|
DownloadManager.Query query = new DownloadManager.Query();
|
325
|
371
|
query.setFilterById(downloadManagerId);
|
326
|
372
|
DownloadManager dm = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
|
|
@@ -329,13 +375,19 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
329
|
375
|
if (c.moveToFirst()) {
|
330
|
376
|
String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
|
331
|
377
|
Uri uri = Uri.parse(contentUri);
|
332
|
|
- Cursor cursor = ctx.getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
|
333
|
|
- cursor.moveToFirst();
|
334
|
|
- String filePath = cursor.getString(0);
|
335
|
|
- cursor.close();
|
336
|
|
- this.callback.invoke(null, filePath);
|
|
378
|
+ Cursor cursor = ctx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
|
|
379
|
+ if (cursor != null) {
|
|
380
|
+ cursor.moveToFirst();
|
|
381
|
+ String filePath = cursor.getString(0);
|
|
382
|
+ cursor.close();
|
|
383
|
+ this.callback.invoke(null, filePath);
|
|
384
|
+ }
|
|
385
|
+ else
|
|
386
|
+ this.callback.invoke(null, null);
|
337
|
387
|
}
|
338
|
388
|
}
|
339
|
389
|
}
|
340
|
390
|
}
|
|
391
|
+
|
|
392
|
+
|
341
|
393
|
}
|