react-native-blob-util 0.13.15 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +472 -407
- package/android/build.gradle +49 -39
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +98 -41
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilBody.java +14 -15
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +8 -6
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +23 -291
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilMediaCollection.java +278 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilPackage.java +6 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +29 -23
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +287 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilUtils.java +57 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +5 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -0
- package/fetch.js +1 -1
- package/fs.js +2 -1
- package/index.d.ts +108 -3
- package/index.js +2 -0
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m +2 -1
- package/ios/ReactNativeBlobUtilFS.h +1 -0
- package/ios/ReactNativeBlobUtilFS.m +4 -0
- package/ios/ReactNativeBlobUtilReqBuilder.m +1 -0
- package/mediacollection.js +33 -0
- package/package.json +1 -1
- package/scripts/prelink.js +1 -1
- package/types.js +3 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
package com.ReactNativeBlobUtil;
|
|
2
|
+
|
|
3
|
+
import android.content.ContentResolver;
|
|
4
|
+
import android.content.ContentValues;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.net.Uri;
|
|
7
|
+
import android.os.Build;
|
|
8
|
+
import android.os.Environment;
|
|
9
|
+
import android.os.ParcelFileDescriptor;
|
|
10
|
+
import android.provider.MediaStore;
|
|
11
|
+
import android.util.Base64;
|
|
12
|
+
|
|
13
|
+
import androidx.annotation.RequiresApi;
|
|
14
|
+
|
|
15
|
+
import com.ReactNativeBlobUtil.Utils.FileDescription;
|
|
16
|
+
import com.facebook.react.bridge.Arguments;
|
|
17
|
+
import com.facebook.react.bridge.Promise;
|
|
18
|
+
import com.facebook.react.bridge.WritableArray;
|
|
19
|
+
|
|
20
|
+
import java.io.File;
|
|
21
|
+
import java.io.FileInputStream;
|
|
22
|
+
import java.io.FileOutputStream;
|
|
23
|
+
import java.io.IOException;
|
|
24
|
+
import java.io.InputStream;
|
|
25
|
+
import java.io.OutputStream;
|
|
26
|
+
|
|
27
|
+
public class ReactNativeBlobUtilMediaCollection {
|
|
28
|
+
|
|
29
|
+
public enum MediaType {
|
|
30
|
+
Audio,
|
|
31
|
+
Image,
|
|
32
|
+
Video,
|
|
33
|
+
Download
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private static Uri getMediaUri(MediaType mt) {
|
|
37
|
+
Uri res = null;
|
|
38
|
+
if (mt == MediaType.Audio) {
|
|
39
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
40
|
+
res = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
|
41
|
+
} else {
|
|
42
|
+
res = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
43
|
+
}
|
|
44
|
+
} else if (mt == MediaType.Video) {
|
|
45
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
46
|
+
res = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
|
47
|
+
} else {
|
|
48
|
+
res = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
49
|
+
}
|
|
50
|
+
} else if (mt == MediaType.Image) {
|
|
51
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
52
|
+
res = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
|
53
|
+
} else {
|
|
54
|
+
res = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
55
|
+
}
|
|
56
|
+
} else if (mt == MediaType.Download) {
|
|
57
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
58
|
+
res = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private static String getRelativePath(MediaType mt) {
|
|
66
|
+
if (mt == MediaType.Audio) return Environment.DIRECTORY_MUSIC;
|
|
67
|
+
if (mt == MediaType.Video) return Environment.DIRECTORY_MOVIES;
|
|
68
|
+
if (mt == MediaType.Image) return Environment.DIRECTORY_PICTURES;
|
|
69
|
+
if (mt == MediaType.Download) return Environment.DIRECTORY_DOWNLOADS;
|
|
70
|
+
return Environment.DIRECTORY_DOWNLOADS;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public static Uri createNewMediaFile(FileDescription file, MediaType mt) {
|
|
74
|
+
// Add a specific media item.
|
|
75
|
+
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
76
|
+
ContentResolver resolver = appCtx.getContentResolver();
|
|
77
|
+
|
|
78
|
+
ContentValues fileDetails = new ContentValues();
|
|
79
|
+
String relativePath = getRelativePath(mt);
|
|
80
|
+
String mimeType = file.mimeType;
|
|
81
|
+
|
|
82
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
83
|
+
fileDetails.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis() / 1000);
|
|
84
|
+
fileDetails.put(MediaStore.MediaColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000);
|
|
85
|
+
fileDetails.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
|
|
86
|
+
fileDetails.put(MediaStore.MediaColumns.DISPLAY_NAME, file.name);
|
|
87
|
+
fileDetails.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath + '/' + file.partentFolder);
|
|
88
|
+
|
|
89
|
+
Uri mediauri = getMediaUri(mt);
|
|
90
|
+
|
|
91
|
+
// Keeps a handle to the new file's URI in case we need to modify it later.
|
|
92
|
+
return resolver.insert(mediauri, fileDetails);
|
|
93
|
+
} else {
|
|
94
|
+
File directory = Environment.getExternalStoragePublicDirectory(relativePath);
|
|
95
|
+
if (directory.canWrite()) {
|
|
96
|
+
File f = new File(relativePath + '/' + file.getFullPath());
|
|
97
|
+
if (!f.exists()) {
|
|
98
|
+
boolean result = f.mkdirs();
|
|
99
|
+
if (result) return Uri.fromFile(f);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
109
|
+
public static boolean writeToMediaFile(Uri fileUri, String data, Promise promise) {
|
|
110
|
+
try {
|
|
111
|
+
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
112
|
+
ContentResolver resolver = appCtx.getContentResolver();
|
|
113
|
+
|
|
114
|
+
// set pending
|
|
115
|
+
ContentValues contentValues = new ContentValues();
|
|
116
|
+
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
|
|
117
|
+
resolver.update(fileUri, contentValues, null, null);
|
|
118
|
+
|
|
119
|
+
// write data
|
|
120
|
+
OutputStream stream = null;
|
|
121
|
+
Uri uri = null;
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
ParcelFileDescriptor descr;
|
|
125
|
+
try {
|
|
126
|
+
assert fileUri != null;
|
|
127
|
+
descr = appCtx.getContentResolver().openFileDescriptor(fileUri, "w");
|
|
128
|
+
assert descr != null;
|
|
129
|
+
String normalizedData = ReactNativeBlobUtilUtils.normalizePath(data);
|
|
130
|
+
File src = new File(normalizedData);
|
|
131
|
+
if (!src.exists()) {
|
|
132
|
+
promise.reject("ENOENT", "No such file ('" + normalizedData + "')");
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
byte[] buf = new byte[10240];
|
|
136
|
+
int read;
|
|
137
|
+
int written = 0;
|
|
138
|
+
|
|
139
|
+
FileInputStream fin = new FileInputStream(src);
|
|
140
|
+
FileOutputStream out = new FileOutputStream(descr.getFileDescriptor());
|
|
141
|
+
|
|
142
|
+
while ((read = fin.read(buf)) > 0) {
|
|
143
|
+
out.write(buf, 0, read);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
fin.close();
|
|
147
|
+
out.close();
|
|
148
|
+
descr.close();
|
|
149
|
+
} catch (Exception e) {
|
|
150
|
+
e.printStackTrace();
|
|
151
|
+
promise.reject(new IOException("Failed to get output stream."));
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
contentValues.clear();
|
|
156
|
+
contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
|
|
157
|
+
appCtx.getContentResolver().update(fileUri, contentValues, null, null);
|
|
158
|
+
stream = resolver.openOutputStream(fileUri);
|
|
159
|
+
if (stream == null) {
|
|
160
|
+
promise.reject(new IOException("Failed to get output stream."));
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
} catch (IOException e) {
|
|
164
|
+
// Don't leave an orphan entry in the MediaStore
|
|
165
|
+
resolver.delete(uri, null, null);
|
|
166
|
+
promise.reject(e);
|
|
167
|
+
return false;
|
|
168
|
+
} finally {
|
|
169
|
+
if (stream != null) {
|
|
170
|
+
stream.close();
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// remove pending
|
|
176
|
+
contentValues = new ContentValues();
|
|
177
|
+
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
|
|
178
|
+
resolver.update(fileUri, contentValues, null, null);
|
|
179
|
+
|
|
180
|
+
} catch (IOException e) {
|
|
181
|
+
promise.reject("ReactNativeBlobUtil.createMediaFile", "Cannot write to file, file might not exist");
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public static void copyToInternal(Uri contenturi, String destpath, Promise promise) {
|
|
188
|
+
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
189
|
+
ContentResolver resolver = appCtx.getContentResolver();
|
|
190
|
+
|
|
191
|
+
InputStream in = null;
|
|
192
|
+
OutputStream out = null;
|
|
193
|
+
|
|
194
|
+
if (!new File(destpath).exists()) {
|
|
195
|
+
try {
|
|
196
|
+
boolean result = new File(destpath).createNewFile();
|
|
197
|
+
if (!result) {
|
|
198
|
+
promise.reject("ReactNativeBlobUtil.copyToInternal: Destination file at '" + destpath + "' already exists");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
} catch (IOException ioException) {
|
|
202
|
+
promise.reject("ReactNativeBlobUtil.copyToInternal: Could not create file: " + ioException.getLocalizedMessage());
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
in = resolver.openInputStream(contenturi);
|
|
208
|
+
out = new FileOutputStream(destpath);
|
|
209
|
+
|
|
210
|
+
byte[] buf = new byte[10240];
|
|
211
|
+
int len;
|
|
212
|
+
while ((len = in.read(buf)) > 0) {
|
|
213
|
+
out.write(buf, 0, len);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
} catch (IOException e) {
|
|
217
|
+
promise.reject("ReactNativeBlobUtil.copyToInternal: Could not write data: " + e.getLocalizedMessage());
|
|
218
|
+
} finally {
|
|
219
|
+
if (in != null) {
|
|
220
|
+
try {
|
|
221
|
+
in.close();
|
|
222
|
+
} catch (IOException ioException) {
|
|
223
|
+
ioException.printStackTrace();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (out != null) {
|
|
227
|
+
try {
|
|
228
|
+
out.close();
|
|
229
|
+
} catch (IOException ioException) {
|
|
230
|
+
ioException.printStackTrace();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
promise.resolve("");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
public static void getBlob(Uri contentUri, String encoding, Promise promise) {
|
|
239
|
+
Context appCtx = ReactNativeBlobUtil.RCTContext.getApplicationContext();
|
|
240
|
+
ContentResolver resolver = appCtx.getContentResolver();
|
|
241
|
+
try {
|
|
242
|
+
InputStream in = resolver.openInputStream(contentUri);
|
|
243
|
+
int length = 0;
|
|
244
|
+
|
|
245
|
+
length = in.available();
|
|
246
|
+
|
|
247
|
+
byte[] bytes = new byte[length];
|
|
248
|
+
int bytesRead = in.read(bytes);
|
|
249
|
+
in.close();
|
|
250
|
+
|
|
251
|
+
if (bytesRead < length) {
|
|
252
|
+
promise.reject("EUNSPECIFIED", "Read only " + bytesRead + " bytes of " + length);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
switch (encoding.toLowerCase()) {
|
|
257
|
+
case "base64":
|
|
258
|
+
promise.resolve(Base64.encodeToString(bytes, Base64.NO_WRAP));
|
|
259
|
+
break;
|
|
260
|
+
case "ascii":
|
|
261
|
+
WritableArray asciiResult = Arguments.createArray();
|
|
262
|
+
for (byte b : bytes) {
|
|
263
|
+
asciiResult.pushInt((int) b);
|
|
264
|
+
}
|
|
265
|
+
promise.resolve(asciiResult);
|
|
266
|
+
break;
|
|
267
|
+
case "utf8":
|
|
268
|
+
promise.resolve(new String(bytes));
|
|
269
|
+
break;
|
|
270
|
+
default:
|
|
271
|
+
promise.resolve(new String(bytes));
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
} catch (IOException ioException) {
|
|
275
|
+
ioException.printStackTrace();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.ReactNativeBlobUtil;
|
|
2
2
|
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
|
|
3
5
|
import com.facebook.react.ReactPackage;
|
|
4
6
|
import com.facebook.react.bridge.JavaScriptModule;
|
|
5
7
|
import com.facebook.react.bridge.NativeModule;
|
|
@@ -13,8 +15,9 @@ import java.util.List;
|
|
|
13
15
|
|
|
14
16
|
public class ReactNativeBlobUtilPackage implements ReactPackage {
|
|
15
17
|
|
|
18
|
+
@NonNull
|
|
16
19
|
@Override
|
|
17
|
-
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
20
|
+
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
|
18
21
|
List<NativeModule> modules = new ArrayList<>();
|
|
19
22
|
modules.add(new ReactNativeBlobUtil(reactContext));
|
|
20
23
|
return modules;
|
|
@@ -24,8 +27,9 @@ public class ReactNativeBlobUtilPackage implements ReactPackage {
|
|
|
24
27
|
return Collections.emptyList();
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
@NonNull
|
|
27
31
|
@Override
|
|
28
|
-
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
32
|
+
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
|
29
33
|
return Collections.emptyList();
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -30,33 +30,27 @@ import com.facebook.react.bridge.WritableArray;
|
|
|
30
30
|
import com.facebook.react.bridge.WritableMap;
|
|
31
31
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
32
32
|
|
|
33
|
-
import javax.net.ssl.TrustManagerFactory;
|
|
34
|
-
import javax.net.ssl.TrustManager;
|
|
35
|
-
import javax.net.ssl.X509TrustManager;
|
|
36
|
-
import javax.net.ssl.SSLContext;
|
|
37
|
-
|
|
38
33
|
import java.io.File;
|
|
39
34
|
import java.io.FileOutputStream;
|
|
40
35
|
import java.io.IOException;
|
|
41
36
|
import java.io.InputStream;
|
|
42
37
|
import java.net.MalformedURLException;
|
|
38
|
+
import java.net.Proxy;
|
|
43
39
|
import java.net.SocketException;
|
|
44
40
|
import java.net.SocketTimeoutException;
|
|
45
41
|
import java.net.URL;
|
|
46
|
-
import java.net.Proxy;
|
|
47
42
|
import java.nio.ByteBuffer;
|
|
48
43
|
import java.nio.charset.CharacterCodingException;
|
|
49
44
|
import java.nio.charset.Charset;
|
|
50
45
|
import java.nio.charset.CharsetDecoder;
|
|
51
|
-
import java.security.KeyStore;
|
|
52
46
|
import java.util.ArrayList;
|
|
53
|
-
import java.util.Arrays;
|
|
54
|
-
import java.util.List;
|
|
55
47
|
import java.util.HashMap;
|
|
56
48
|
|
|
49
|
+
import java.util.List;
|
|
50
|
+
import java.util.Locale;
|
|
57
51
|
import java.util.concurrent.TimeUnit;
|
|
58
52
|
|
|
59
|
-
import javax.net.ssl.
|
|
53
|
+
import javax.net.ssl.SSLContext;
|
|
60
54
|
|
|
61
55
|
import okhttp3.Call;
|
|
62
56
|
import okhttp3.ConnectionPool;
|
|
@@ -120,7 +114,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
120
114
|
OkHttpClient client;
|
|
121
115
|
|
|
122
116
|
public ReactNativeBlobUtilReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, OkHttpClient client, final Callback callback) {
|
|
123
|
-
this.method = method.toUpperCase();
|
|
117
|
+
this.method = method.toUpperCase(Locale.ROOT);
|
|
124
118
|
this.options = new ReactNativeBlobUtilConfig(options);
|
|
125
119
|
this.taskId = taskId;
|
|
126
120
|
this.url = url;
|
|
@@ -196,7 +190,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
196
190
|
req.addRequestHeader(key, headers.getString(key));
|
|
197
191
|
}
|
|
198
192
|
// Attempt to add cookie, if it exists
|
|
199
|
-
URL urlObj
|
|
193
|
+
URL urlObj;
|
|
200
194
|
try {
|
|
201
195
|
urlObj = new URL(url);
|
|
202
196
|
String baseUrl = urlObj.getProtocol() + "://" + urlObj.getHost();
|
|
@@ -311,14 +305,14 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
311
305
|
else if (value.equalsIgnoreCase("utf8"))
|
|
312
306
|
responseFormat = ResponseFormat.UTF8;
|
|
313
307
|
} else {
|
|
314
|
-
builder.header(key.toLowerCase(), value);
|
|
315
|
-
mheaders.put(key.toLowerCase(), value);
|
|
308
|
+
builder.header(key.toLowerCase(Locale.ROOT), value);
|
|
309
|
+
mheaders.put(key.toLowerCase(Locale.ROOT), value);
|
|
316
310
|
}
|
|
317
311
|
}
|
|
318
312
|
}
|
|
319
313
|
|
|
320
314
|
if (method.equalsIgnoreCase("post") || method.equalsIgnoreCase("put") || method.equalsIgnoreCase("patch")) {
|
|
321
|
-
String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase();
|
|
315
|
+
String cType = getHeaderIgnoreCases(mheaders, "Content-Type").toLowerCase(Locale.ROOT);
|
|
322
316
|
|
|
323
317
|
if (rawRequestBodyArray != null) {
|
|
324
318
|
requestType = RequestType.Form;
|
|
@@ -332,7 +326,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
332
326
|
if (rawRequestBody.startsWith(ReactNativeBlobUtilConst.FILE_PREFIX)
|
|
333
327
|
|| rawRequestBody.startsWith(ReactNativeBlobUtilConst.CONTENT_PREFIX)) {
|
|
334
328
|
requestType = RequestType.SingleFile;
|
|
335
|
-
} else if (cType.toLowerCase().contains(";base64") || cType.toLowerCase().startsWith("application/octet")) {
|
|
329
|
+
} else if (cType.toLowerCase(Locale.ROOT).contains(";base64") || cType.toLowerCase(Locale.ROOT).startsWith("application/octet")) {
|
|
336
330
|
cType = cType.replace(";base64", "").replace(";BASE64", "");
|
|
337
331
|
if (mheaders.containsKey("content-type"))
|
|
338
332
|
mheaders.put("content-type", cType);
|
|
@@ -388,18 +382,21 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
388
382
|
// #156 fix cookie issue
|
|
389
383
|
final Request req = builder.build();
|
|
390
384
|
clientBuilder.addNetworkInterceptor(new Interceptor() {
|
|
385
|
+
@NonNull
|
|
391
386
|
@Override
|
|
392
|
-
public Response intercept(Chain chain) throws IOException {
|
|
387
|
+
public Response intercept(@NonNull Chain chain) throws IOException {
|
|
393
388
|
redirects.add(chain.request().url().toString());
|
|
394
389
|
return chain.proceed(chain.request());
|
|
395
390
|
}
|
|
396
391
|
});
|
|
397
392
|
// Add request interceptor for upload progress event
|
|
398
393
|
clientBuilder.addInterceptor(new Interceptor() {
|
|
394
|
+
@NonNull
|
|
399
395
|
@Override
|
|
400
396
|
public Response intercept(@NonNull Chain chain) throws IOException {
|
|
397
|
+
Response originalResponse = null;
|
|
401
398
|
try {
|
|
402
|
-
|
|
399
|
+
originalResponse = chain.proceed(req);
|
|
403
400
|
ResponseBody extended;
|
|
404
401
|
switch (responseType) {
|
|
405
402
|
case KeepInMemory:
|
|
@@ -428,12 +425,21 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
428
425
|
return originalResponse.newBuilder().body(extended).build();
|
|
429
426
|
} catch (SocketException e) {
|
|
430
427
|
timeout = true;
|
|
428
|
+
if (originalResponse != null) {
|
|
429
|
+
originalResponse.close();
|
|
430
|
+
}
|
|
431
431
|
} catch (SocketTimeoutException e) {
|
|
432
432
|
timeout = true;
|
|
433
|
+
if (originalResponse != null) {
|
|
434
|
+
originalResponse.close();
|
|
435
|
+
}
|
|
433
436
|
//ReactNativeBlobUtilUtils.emitWarningEvent("ReactNativeBlobUtil error when sending request : " + e.getLocalizedMessage());
|
|
434
437
|
} catch (Exception ex) {
|
|
435
|
-
|
|
438
|
+
if (originalResponse != null) {
|
|
439
|
+
originalResponse.close();
|
|
440
|
+
}
|
|
436
441
|
}
|
|
442
|
+
|
|
437
443
|
return chain.proceed(chain.request());
|
|
438
444
|
}
|
|
439
445
|
});
|
|
@@ -457,7 +463,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
457
463
|
call.enqueue(new okhttp3.Callback() {
|
|
458
464
|
|
|
459
465
|
@Override
|
|
460
|
-
public void onFailure(@NonNull Call call, IOException e) {
|
|
466
|
+
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
|
461
467
|
cancelTask(taskId);
|
|
462
468
|
if (respInfo == null) {
|
|
463
469
|
respInfo = Arguments.createMap();
|
|
@@ -708,7 +714,7 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
708
714
|
boolean isCustomBinary = false;
|
|
709
715
|
if (options.binaryContentTypes != null) {
|
|
710
716
|
for (int i = 0; i < options.binaryContentTypes.size(); i++) {
|
|
711
|
-
if (ctype.toLowerCase().contains(options.binaryContentTypes.getString(i).toLowerCase())) {
|
|
717
|
+
if (ctype.toLowerCase(Locale.ROOT).contains(options.binaryContentTypes.getString(i).toLowerCase(Locale.ROOT))) {
|
|
712
718
|
isCustomBinary = true;
|
|
713
719
|
break;
|
|
714
720
|
}
|
|
@@ -720,13 +726,13 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
720
726
|
private String getHeaderIgnoreCases(Headers headers, String field) {
|
|
721
727
|
String val = headers.get(field);
|
|
722
728
|
if (val != null) return val;
|
|
723
|
-
return headers.get(field.toLowerCase()) == null ? "" : headers.get(field.toLowerCase());
|
|
729
|
+
return headers.get(field.toLowerCase(Locale.ROOT)) == null ? "" : headers.get(field.toLowerCase(Locale.ROOT));
|
|
724
730
|
}
|
|
725
731
|
|
|
726
732
|
private String getHeaderIgnoreCases(HashMap<String, String> headers, String field) {
|
|
727
733
|
String val = headers.get(field);
|
|
728
734
|
if (val != null) return val;
|
|
729
|
-
String lowerCasedValue = headers.get(field.toLowerCase());
|
|
735
|
+
String lowerCasedValue = headers.get(field.toLowerCase(Locale.ROOT));
|
|
730
736
|
return lowerCasedValue == null ? "" : lowerCasedValue;
|
|
731
737
|
}
|
|
732
738
|
|