Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit 87fcc36

Browse files
author
amoreno
committed
Merge branch 'master' into _parametrizable_ui_document_interaction_controller
2 parents 429cc68 + 821eeb0 commit 87fcc36

11 files changed

+115
-26
lines changed

.github/PULL_REQUEST_TEMPLATE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Thank you for making a pull request ! Just a gentle reminder :)
22

33
1. If the PR is offering a feature please make the request to our "Feature Branch" 0.11.0
4-
2. Bug fix request to "Bug Fix Branch" 0.10.7
4+
2. Bug fix request to "Bug Fix Branch" 0.10.9
55
3. Correct README.md can directly to master

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ RNFetchBlob
236236
console.log('The file saved to ', res.path())
237237
// Beware that when using a file path as Image source on Android,
238238
// you must prepend "file://"" before the file path
239-
imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
239+
imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
240240
})
241241
```
242242

android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java

+23-6
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,28 @@ static public void writeFile(String path, ReadableArray data, final boolean appe
138138
* @param promise
139139
*/
140140
static public void readFile(String path, String encoding, final Promise promise ) {
141-
path = normalizePath(path);
141+
String resolved = normalizePath(path);
142+
if(resolved != null)
143+
path = resolved;
142144
try {
143145
byte[] bytes;
144146

145-
if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
147+
if(resolved != null && resolved.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
146148
String assetName = path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, "");
147149
long length = RNFetchBlob.RCTContext.getAssets().openFd(assetName).getLength();
148150
bytes = new byte[(int) length];
149151
InputStream in = RNFetchBlob.RCTContext.getAssets().open(assetName);
150152
in.read(bytes, 0, (int) length);
151153
in.close();
152154
}
155+
// issue 287
156+
else if(resolved == null) {
157+
InputStream in = RNFetchBlob.RCTContext.getContentResolver().openInputStream(Uri.parse(path));
158+
int length = (int) in.available();
159+
bytes = new byte[length];
160+
in.read(bytes);
161+
in.close();
162+
}
153163
else {
154164
File f = new File(path);
155165
int length = (int) f.length();
@@ -226,17 +236,24 @@ static public String getTmpPath(ReactApplicationContext ctx, String taskId) {
226236
* @param bufferSize Buffer size of read stream, default to 4096 (4095 when encode is `base64`)
227237
*/
228238
public void readStream(String path, String encoding, int bufferSize, int tick, final String streamId) {
229-
path = normalizePath(path);
239+
String resolved = normalizePath(path);
240+
if(resolved != null)
241+
path = resolved;
230242
try {
231243

232244
int chunkSize = encoding.equalsIgnoreCase("base64") ? 4095 : 4096;
233245
if(bufferSize > 0)
234246
chunkSize = bufferSize;
235247

236248
InputStream fs;
237-
if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
238-
fs = RNFetchBlob.RCTContext.getAssets()
239-
.open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));
249+
250+
if(resolved != null && path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
251+
fs = RNFetchBlob.RCTContext.getAssets().open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));
252+
253+
}
254+
// fix issue 287
255+
else if(resolved == null) {
256+
fs = RNFetchBlob.RCTContext.getContentResolver().openInputStream(Uri.parse(path));
240257
}
241258
else {
242259
fs = new FileInputStream(new File(path));

android/src/main/java/com/RNFetchBlob/RNFetchBlobPackage.java

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ public List<NativeModule> createNativeModules(ReactApplicationContext reactConte
2020
return modules;
2121
}
2222

23-
@Override
2423
public List<Class<? extends JavaScriptModule>> createJSModules() {
2524
return Collections.emptyList();
2625
}

android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java

+46-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import android.content.IntentFilter;
88
import android.database.Cursor;
99
import android.net.Uri;
10+
import android.os.Build;
1011
import android.util.Base64;
1112

1213
import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
1314
import com.RNFetchBlob.Response.RNFetchBlobFileResp;
15+
import com.facebook.common.logging.FLog;
1416
import com.facebook.react.bridge.Arguments;
1517
import com.facebook.react.bridge.Callback;
1618
import com.facebook.react.bridge.ReactApplicationContext;
@@ -21,6 +23,7 @@
2123
import com.facebook.react.bridge.WritableMap;
2224
import com.facebook.react.modules.core.DeviceEventManagerModule;
2325
import com.facebook.react.modules.network.OkHttpClientProvider;
26+
import com.facebook.react.modules.network.TLSSocketFactory;
2427

2528
import java.io.File;
2629
import java.io.FileOutputStream;
@@ -35,11 +38,14 @@
3538
import java.nio.charset.Charset;
3639
import java.nio.charset.CharsetEncoder;
3740
import java.util.ArrayList;
41+
import java.util.List;
3842
import java.util.HashMap;
43+
3944
import java.util.concurrent.TimeUnit;
4045

4146
import okhttp3.Call;
4247
import okhttp3.ConnectionPool;
48+
import okhttp3.ConnectionSpec;
4349
import okhttp3.Headers;
4450
import okhttp3.Interceptor;
4551
import okhttp3.MediaType;
@@ -48,6 +54,8 @@
4854
import okhttp3.RequestBody;
4955
import okhttp3.Response;
5056
import okhttp3.ResponseBody;
57+
import okhttp3.TlsVersion;
58+
5159

5260
public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
5361

@@ -148,8 +156,15 @@ public void run() {
148156
if(options.addAndroidDownloads.hasKey("path")) {
149157
req.setDestinationUri(Uri.parse("file://" + options.addAndroidDownloads.getString("path")));
150158
}
159+
// #391 Add MIME type to the request
160+
if(options.addAndroidDownloads.hasKey("mime")) {
161+
req.setMimeType(options.addAndroidDownloads.getString("mime"));
162+
}
151163
// set headers
152164
ReadableMapKeySetIterator it = headers.keySetIterator();
165+
if(options.addAndroidDownloads.hasKey("mediaScannable") && options.addAndroidDownloads.hasKey("mediaScannable") == true ) {
166+
req.allowScanningByMediaScanner();
167+
}
153168
while (it.hasNextKey()) {
154169
String key = it.nextKey();
155170
req.addRequestHeader(key, headers.getString(key));
@@ -359,9 +374,10 @@ public Response intercept(Chain chain) throws IOException {
359374
clientBuilder.retryOnConnectionFailure(false);
360375
clientBuilder.followRedirects(options.followRedirect);
361376
clientBuilder.followSslRedirects(options.followRedirect);
377+
clientBuilder.retryOnConnectionFailure(true);
362378

379+
OkHttpClient client = enableTls12OnPreLollipop(clientBuilder).build();
363380

364-
OkHttpClient client = clientBuilder.retryOnConnectionFailure(true).build();
365381
Call call = client.newCall(req);
366382
taskTable.put(taskId, call);
367383
call.enqueue(new okhttp3.Callback() {
@@ -636,16 +652,20 @@ public void onReceive(Context context, Intent intent) {
636652
return;
637653
}
638654
String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
639-
if (contentUri != null) {
655+
if ( contentUri != null &&
656+
options.addAndroidDownloads.hasKey("mime") &&
657+
options.addAndroidDownloads.getString("mime").contains("image")) {
640658
Uri uri = Uri.parse(contentUri);
641659
Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
642-
// use default destination of DownloadManager
660+
661+
// use default destination of DownloadManager
643662
if (cursor != null) {
644663
cursor.moveToFirst();
645664
filePath = cursor.getString(0);
646665
}
647666
}
648667
}
668+
649669
// When the file is not found in media content database, check if custom path exists
650670
if (options.addAndroidDownloads.hasKey("path")) {
651671
try {
@@ -672,5 +692,28 @@ public void onReceive(Context context, Intent intent) {
672692
}
673693
}
674694

695+
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
696+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
697+
try {
698+
client.sslSocketFactory(new TLSSocketFactory());
699+
700+
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
701+
.tlsVersions(TlsVersion.TLS_1_2)
702+
.build();
703+
704+
List< ConnectionSpec > specs = new ArrayList < > ();
705+
specs.add(cs);
706+
specs.add(ConnectionSpec.COMPATIBLE_TLS);
707+
specs.add(ConnectionSpec.CLEARTEXT);
708+
709+
client.connectionSpecs(specs);
710+
} catch (Exception exc) {
711+
FLog.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
712+
}
713+
}
714+
715+
return client;
716+
}
717+
675718

676719
}

android/src/main/java/com/RNFetchBlob/Utils/PathResolver.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,16 @@ else if (isMediaDocument(uri)) {
6464

6565
return getDataColumn(context, contentUri, selection, selectionArgs);
6666
}
67+
else if ("content".equalsIgnoreCase(uri.getScheme())) {
68+
69+
// Return the remote address
70+
if (isGooglePhotosUri(uri))
71+
return uri.getLastPathSegment();
72+
73+
return getDataColumn(context, uri, null, null);
74+
}
6775
// Other Providers
68-
else {
76+
else{
6977
try {
7078
InputStream attachment = context.getContentResolver().openInputStream(uri);
7179
if (attachment != null) {
@@ -131,6 +139,7 @@ public static String getDataColumn(Context context, Uri uri, String selection,
131139
String[] selectionArgs) {
132140

133141
Cursor cursor = null;
142+
String result = null;
134143
final String column = "_data";
135144
final String[] projection = {
136145
column
@@ -141,13 +150,18 @@ public static String getDataColumn(Context context, Uri uri, String selection,
141150
null);
142151
if (cursor != null && cursor.moveToFirst()) {
143152
final int index = cursor.getColumnIndexOrThrow(column);
144-
return cursor.getString(index);
153+
result = cursor.getString(index);
145154
}
146-
} finally {
155+
}
156+
catch (Exception ex) {
157+
ex.printStackTrace();
158+
return null;
159+
}
160+
finally {
147161
if (cursor != null)
148162
cursor.close();
149163
}
150-
return null;
164+
return result;
151165
}
152166

153167

ios.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function openDocument(path:string, fontFamily:string, fontSize: number, hexStrin
4343
* @param {string} url URL of the resource, only file URL is supported
4444
* @return {Promise}
4545
*/
46-
function excludeFromBackupKey(url:string) {
46+
function excludeFromBackupKey(path:string) {
4747
return RNFetchBlob.excludeFromBackupKey('file://' + path);
4848
}
4949

ios/RNFetchBlobFS.m

+5-5
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,11 @@ - (NSString *)openWithPath:(NSString *)destPath encode:(nullable NSString *)enco
568568

569569
// Write file chunk into an opened stream
570570
- (void)writeEncodeChunk:(NSString *) chunk {
571-
NSMutableData * decodedData = [NSData alloc];
571+
NSData * decodedData = nil;
572572
if([[self.encoding lowercaseString] isEqualToString:@"base64"]) {
573-
decodedData = [[NSData alloc] initWithBase64EncodedData:chunk options:0];
574-
}
575-
if([[self.encoding lowercaseString] isEqualToString:@"utf8"]) {
573+
decodedData = [[NSData alloc] initWithBase64EncodedString:chunk options: NSDataBase64DecodingIgnoreUnknownCharacters];
574+
}
575+
else if([[self.encoding lowercaseString] isEqualToString:@"utf8"]) {
576576
decodedData = [chunk dataUsingEncoding:NSUTF8StringEncoding];
577577
}
578578
else if([[self.encoding lowercaseString] isEqualToString:@"ascii"]) {
@@ -793,4 +793,4 @@ + (void) writeAssetToPath:(ALAssetRepresentation * )rep dest:(NSString *)dest
793793
return;
794794
}
795795

796-
@end
796+
@end

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"name": "react-native-fetch-blob",
3-
"version": "0.10.6",
3+
"version": "0.10.8",
44
"description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
55
"main": "index.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1"
88
},
99
"dependencies": {
1010
"base-64": "0.1.0",
11-
"glob": "^7.0.6"
11+
"glob": "7.0.6"
1212
},
1313
"keywords": [
1414
"react-native",
@@ -35,4 +35,4 @@
3535
3636
""
3737
]
38-
}
38+
}

polyfill/Blob.js

+16
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ export default class Blob extends EventTarget {
130130
// Blob data from file path
131131
else if(typeof data === 'string' && data.startsWith('RNFetchBlob-file://')) {
132132
log.verbose('create Blob cache file from file path', data)
133+
// set this flag so that we know this blob is a wrapper of an existing file
134+
this._isReference = true
133135
this._ref = String(data).replace('RNFetchBlob-file://', '')
134136
let orgPath = this._ref
135137
if(defer)
@@ -282,6 +284,20 @@ export default class Blob extends EventTarget {
282284
})
283285
}
284286

287+
safeClose() {
288+
if(this._closed)
289+
return Promise.reject('Blob has been released.')
290+
this._closed = true
291+
if(!this._isReference) {
292+
return fs.unlink(this._ref).catch((err) => {
293+
console.warn(err)
294+
})
295+
}
296+
else {
297+
return Promise.resolve()
298+
}
299+
}
300+
285301
_invokeOnCreateEvent() {
286302
log.verbose('invoke create event', this._onCreated)
287303
this._blobCreated = true

polyfill/XMLHttpRequest.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
277277
_headerReceived = (e) => {
278278
log.debug('header received ', this._task.taskId, e)
279279
this.responseURL = this._url
280-
if(e.state === "2") {
280+
if(e.state === "2" && e.taskId === this._task.taskId) {
281281
this._responseHeaders = e.headers
282282
this._statusText = e.status
283283
this._status = Math.floor(e.status)

0 commit comments

Comments
 (0)