|
@@ -7,8 +7,8 @@ import android.content.Intent;
|
7
|
7
|
import android.content.IntentFilter;
|
8
|
8
|
import android.database.Cursor;
|
9
|
9
|
import android.net.Uri;
|
|
10
|
+import android.util.Base64;
|
10
|
11
|
|
11
|
|
-import com.RNFetchBlob.Request.FormPartBody;
|
12
|
12
|
import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
|
13
|
13
|
import com.RNFetchBlob.Response.RNFetchBlobFileResp;
|
14
|
14
|
import com.facebook.react.bridge.Callback;
|
|
@@ -16,14 +16,16 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
16
|
16
|
import com.facebook.react.bridge.ReadableArray;
|
17
|
17
|
import com.facebook.react.bridge.ReadableMap;
|
18
|
18
|
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
19
|
|
-import com.loopj.android.http.Base64;
|
20
|
19
|
|
21
|
20
|
import java.io.ByteArrayInputStream;
|
22
|
21
|
import java.io.File;
|
23
|
22
|
import java.io.FileInputStream;
|
24
|
23
|
import java.io.FileNotFoundException;
|
|
24
|
+import java.io.FileOutputStream;
|
25
|
25
|
import java.io.IOException;
|
26
|
26
|
import java.io.InputStream;
|
|
27
|
+import java.net.MalformedURLException;
|
|
28
|
+import java.net.URL;
|
27
|
29
|
|
28
|
30
|
import okhttp3.Call;
|
29
|
31
|
import okhttp3.Interceptor;
|
|
@@ -33,6 +35,7 @@ import okhttp3.OkHttpClient;
|
33
|
35
|
import okhttp3.Request;
|
34
|
36
|
import okhttp3.RequestBody;
|
35
|
37
|
import okhttp3.Response;
|
|
38
|
+import okhttp3.ResponseBody;
|
36
|
39
|
|
37
|
40
|
/**
|
38
|
41
|
* Created by wkh237 on 2016/6/21.
|
|
@@ -42,12 +45,13 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
42
|
45
|
enum RequestType {
|
43
|
46
|
Form,
|
44
|
47
|
SingleFile,
|
|
48
|
+ WithoutBody,
|
45
|
49
|
Others
|
46
|
50
|
};
|
47
|
51
|
|
48
|
52
|
enum ResponseType {
|
49
|
|
- MemoryCache,
|
50
|
|
- FileCache
|
|
53
|
+ KeepInMemory,
|
|
54
|
+ FileStorage
|
51
|
55
|
};
|
52
|
56
|
|
53
|
57
|
MediaType contentType = RNFetchBlobConst.MIME_OCTET;
|
|
@@ -76,17 +80,17 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
76
|
80
|
this.rawRequestBody = body;
|
77
|
81
|
this.rawRequestBodyArray = arrayBody;
|
78
|
82
|
|
79
|
|
- if(this.options.fileCache != null || this.options.path != null)
|
80
|
|
- responseType = ResponseType.FileCache;
|
|
83
|
+ if(this.options.fileCache == true || this.options.path != null)
|
|
84
|
+ responseType = ResponseType.FileStorage;
|
81
|
85
|
else
|
82
|
|
- responseType = ResponseType.MemoryCache;
|
|
86
|
+ responseType = ResponseType.KeepInMemory;
|
83
|
87
|
|
84
|
88
|
if (body != null)
|
85
|
89
|
requestType = RequestType.SingleFile;
|
86
|
90
|
else if (arrayBody != null)
|
87
|
91
|
requestType = RequestType.Form;
|
88
|
92
|
else
|
89
|
|
- requestType = RequestType.Others;
|
|
93
|
+ requestType = RequestType.WithoutBody;
|
90
|
94
|
}
|
91
|
95
|
|
92
|
96
|
@Override
|
|
@@ -122,109 +126,112 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
122
|
126
|
|
123
|
127
|
// find cached result if `key` property exists
|
124
|
128
|
String cacheKey = this.taskId;
|
125
|
|
- if (this.options.key != null) {
|
126
|
|
- cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
|
127
|
|
- if (cacheKey == null) {
|
128
|
|
- cacheKey = this.taskId;
|
129
|
|
- }
|
130
|
|
-
|
131
|
|
- File file = new File(RNFetchBlobFS.getTmpPath(ctx, cacheKey));
|
132
|
|
- if (file.exists()) {
|
133
|
|
- callback.invoke(null, file.getAbsolutePath());
|
134
|
|
- return;
|
135
|
|
- }
|
136
|
|
- }
|
|
129
|
+// if (this.options.key != null) {
|
|
130
|
+// cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
|
|
131
|
+// if (cacheKey == null) {
|
|
132
|
+// cacheKey = this.taskId;
|
|
133
|
+// }
|
|
134
|
+//
|
|
135
|
+// File file = new File(RNFetchBlobFS.getTmpPath(ctx, cacheKey));
|
|
136
|
+// if (file.exists()) {
|
|
137
|
+// callback.invoke(null, file.getAbsolutePath());
|
|
138
|
+// return;
|
|
139
|
+// }
|
|
140
|
+// }
|
137
|
141
|
|
138
|
142
|
if(this.options.path != null)
|
139
|
|
- destPath = this.options.path;
|
140
|
|
- else if(this.options.fileCache)
|
141
|
|
- destPath = RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey);
|
|
143
|
+ this.destPath = this.options.path;
|
|
144
|
+ else if(this.options.fileCache == true)
|
|
145
|
+ this.destPath = RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey);
|
142
|
146
|
|
143
|
|
- OkHttpClient client;
|
144
|
|
- try {
|
|
147
|
+ OkHttpClient.Builder client;
|
145
|
148
|
|
|
149
|
+// try {
|
146
|
150
|
// use trusty SSL socket
|
147
|
151
|
if (this.options.trusty) {
|
148
|
152
|
client = RNFetchBlobUtils.getUnsafeOkHttpClient();
|
149
|
153
|
} else {
|
150
|
|
- client = new OkHttpClient();
|
|
154
|
+ client = new OkHttpClient.Builder();
|
151
|
155
|
}
|
152
|
156
|
|
153
|
157
|
final Request.Builder builder = new Request.Builder();
|
154
|
|
-
|
|
158
|
+ try {
|
|
159
|
+ builder.url(new URL(url));
|
|
160
|
+ } catch (MalformedURLException e) {
|
|
161
|
+ e.printStackTrace();
|
|
162
|
+ }
|
155
|
163
|
// set headers
|
156
|
164
|
if (headers != null) {
|
157
|
165
|
ReadableMapKeySetIterator it = headers.keySetIterator();
|
158
|
166
|
while (it.hasNextKey()) {
|
159
|
167
|
String key = it.nextKey();
|
160
|
|
- builder.addHeader(key, headers.getString(key));
|
|
168
|
+ String value = headers.getString(key);
|
|
169
|
+ builder.header(key, value);
|
161
|
170
|
}
|
162
|
171
|
}
|
163
|
172
|
|
164
|
173
|
// set request body
|
165
|
174
|
switch (requestType) {
|
166
|
175
|
case SingleFile:
|
|
176
|
+ InputStream dataStream= buildOctetBody(rawRequestBody);
|
167
|
177
|
builder.method(method, new RNFetchBlobBody(
|
168
|
178
|
taskId,
|
169
|
179
|
RequestType.SingleFile,
|
170
|
180
|
null,
|
171
|
|
- buildOctetBody(rawRequestBody),
|
172
|
|
- contentLength
|
|
181
|
+ dataStream,
|
|
182
|
+ contentLength,
|
|
183
|
+ RNFetchBlobConst.MIME_OCTET
|
173
|
184
|
));
|
174
|
185
|
break;
|
175
|
186
|
case Form:
|
176
|
187
|
builder.method(method, new RNFetchBlobBody(
|
177
|
188
|
taskId,
|
178
|
189
|
RequestType.Form,
|
179
|
|
- buildFormBody(rawRequestBodyArray),
|
|
190
|
+ rawRequestBodyArray,
|
180
|
191
|
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
|
|
192
|
+ 0,
|
|
193
|
+ MediaType.parse("multipart/form-data; boundary=RNFetchBlob-" + taskId)
|
190
|
194
|
));
|
191
|
195
|
break;
|
|
196
|
+ case WithoutBody:
|
|
197
|
+ builder.method(method, null);
|
|
198
|
+ break;
|
192
|
199
|
}
|
193
|
200
|
|
194
|
201
|
final Request req = builder.build();
|
195
|
202
|
|
196
|
|
- // create response handler
|
197
|
|
- client.networkInterceptors().add(new Interceptor() {
|
|
203
|
+// create response handler
|
|
204
|
+ client.addInterceptor(new Interceptor() {
|
198
|
205
|
@Override
|
199
|
206
|
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();
|
|
207
|
+ Response originalResponse = chain.proceed(req);
|
|
208
|
+ ResponseBody extended;
|
|
209
|
+ switch (responseType) {
|
|
210
|
+ case KeepInMemory:
|
|
211
|
+ extended = new RNFetchBlobDefaultResp(
|
|
212
|
+ RNFetchBlob.RCTContext,
|
|
213
|
+ taskId,
|
|
214
|
+ originalResponse.body());
|
|
215
|
+ break;
|
|
216
|
+ case FileStorage:
|
|
217
|
+ extended = new RNFetchBlobFileResp(
|
|
218
|
+ RNFetchBlob.RCTContext,
|
|
219
|
+ taskId,
|
|
220
|
+ originalResponse.body(),
|
|
221
|
+ destPath);
|
|
222
|
+ break;
|
|
223
|
+ default:
|
|
224
|
+ extended = new RNFetchBlobDefaultResp(
|
|
225
|
+ RNFetchBlob.RCTContext,
|
|
226
|
+ taskId,
|
|
227
|
+ originalResponse.body());
|
|
228
|
+ break;
|
|
229
|
+ }
|
|
230
|
+ return originalResponse.newBuilder().body(extended).build();
|
224
|
231
|
}
|
225
|
232
|
});
|
226
|
233
|
|
227
|
|
- client.newCall(req).enqueue(new okhttp3.Callback() {
|
|
234
|
+ client.build().newCall(req).enqueue(new okhttp3.Callback() {
|
228
|
235
|
@Override
|
229
|
236
|
public void onFailure(Call call, IOException e) {
|
230
|
237
|
callback.invoke(e.getLocalizedMessage(), null);
|
|
@@ -255,9 +262,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
255
|
262
|
});
|
256
|
263
|
|
257
|
264
|
|
258
|
|
- } catch (Exception error) {
|
259
|
|
- callback.invoke("RNFetchBlob request error: " + error.getMessage() + error.getCause());
|
260
|
|
- }
|
|
265
|
+// } catch (Exception error) {
|
|
266
|
+// error.printStackTrace();
|
|
267
|
+// callback.invoke("RNFetchBlob request error: " + error.getMessage() + error.getCause());
|
|
268
|
+// }
|
261
|
269
|
}
|
262
|
270
|
|
263
|
271
|
/**
|
|
@@ -266,15 +274,22 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
266
|
274
|
*/
|
267
|
275
|
private void done(Response resp) {
|
268
|
276
|
switch (responseType) {
|
269
|
|
- case MemoryCache:
|
|
277
|
+ case KeepInMemory:
|
270
|
278
|
try {
|
271
|
|
- callback.invoke(null, android.util.Base64.encode(resp.body().bytes(), 0));
|
|
279
|
+ byte [] b = resp.body().bytes();
|
|
280
|
+ callback.invoke(null, android.util.Base64.encodeToString(b,Base64.NO_WRAP));
|
272
|
281
|
} catch (IOException e) {
|
273
|
282
|
callback.invoke("RNFetchBlob failed to encode response data to BASE64 string.", null);
|
274
|
283
|
}
|
275
|
284
|
break;
|
276
|
|
- case FileCache:
|
277
|
|
- callback.invoke(null, destPath);
|
|
285
|
+ case FileStorage:
|
|
286
|
+ // write chunk
|
|
287
|
+ try {
|
|
288
|
+ resp.body().bytes();
|
|
289
|
+ } catch (IOException e) {
|
|
290
|
+ e.printStackTrace();
|
|
291
|
+ }
|
|
292
|
+ callback.invoke(null, this.destPath);
|
278
|
293
|
break;
|
279
|
294
|
default:
|
280
|
295
|
try {
|
|
@@ -294,32 +309,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
294
|
309
|
RequestBody buildRawBody(String body) {
|
295
|
310
|
if(body != null) {
|
296
|
311
|
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);
|
319
|
|
- }
|
320
|
|
- return formBuilder.build();
|
|
312
|
+ return RequestBody.create(this.contentType, body);
|
321
|
313
|
}
|
322
|
314
|
return null;
|
|
315
|
+
|
323
|
316
|
}
|
324
|
317
|
|
325
|
318
|
/**
|
|
@@ -337,10 +330,11 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
337
|
330
|
if (body.startsWith(RNFetchBlobConst.FILE_PREFIX)) {
|
338
|
331
|
String orgPath = body.substring(RNFetchBlobConst.FILE_PREFIX.length());
|
339
|
332
|
orgPath = RNFetchBlobFS.normalizePath(orgPath);
|
340
|
|
- // handle
|
|
333
|
+ // upload file from assets
|
341
|
334
|
if (RNFetchBlobFS.isAsset(orgPath)) {
|
342
|
335
|
try {
|
343
|
336
|
String assetName = orgPath.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, "");
|
|
337
|
+ contentLength = RNFetchBlob.RCTContext.getAssets().openFd(assetName).getLength();
|
344
|
338
|
return RNFetchBlob.RCTContext.getAssets().open(assetName);
|
345
|
339
|
} catch (IOException e) {
|
346
|
340
|
// e.printStackTrace();
|
|
@@ -348,13 +342,18 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
|
348
|
342
|
} else {
|
349
|
343
|
File f = new File(RNFetchBlobFS.normalizePath(orgPath));
|
350
|
344
|
try {
|
|
345
|
+ if(!f.exists())
|
|
346
|
+ f.createNewFile();
|
|
347
|
+ contentLength = f.length();
|
351
|
348
|
return new FileInputStream(f);
|
352
|
|
- } catch (FileNotFoundException e) {
|
|
349
|
+ } catch (Exception e) {
|
353
|
350
|
callback.invoke(e.getLocalizedMessage(), null);
|
354
|
351
|
}
|
355
|
352
|
}
|
356
|
353
|
} else {
|
357
|
|
- return new ByteArrayInputStream(Base64.decode(body, 0));
|
|
354
|
+ byte[] bytes = Base64.decode(body, 0);
|
|
355
|
+ contentLength = bytes.length;
|
|
356
|
+ return new ByteArrayInputStream(bytes);
|
358
|
357
|
}
|
359
|
358
|
}
|
360
|
359
|
return null;
|