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

Commit

Permalink
Merge branch 'master' into _parametrizable_ui_document_interaction_co…
Browse files Browse the repository at this point in the history
…ntroller
  • Loading branch information
amoreno committed Oct 24, 2017
2 parents 429cc68 + 821eeb0 commit 87fcc36
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Thank you for making a pull request ! Just a gentle reminder :)

1. If the PR is offering a feature please make the request to our "Feature Branch" 0.11.0
2. Bug fix request to "Bug Fix Branch" 0.10.7
2. Bug fix request to "Bug Fix Branch" 0.10.9
3. Correct README.md can directly to master
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ RNFetchBlob
console.log('The file saved to ', res.path())
// Beware that when using a file path as Image source on Android,
// you must prepend "file://"" before the file path
imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>
})
```

Expand Down
29 changes: 23 additions & 6 deletions android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,28 @@ static public void writeFile(String path, ReadableArray data, final boolean appe
* @param promise
*/
static public void readFile(String path, String encoding, final Promise promise ) {
path = normalizePath(path);
String resolved = normalizePath(path);
if(resolved != null)
path = resolved;
try {
byte[] bytes;

if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
if(resolved != null && resolved.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
String assetName = path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, "");
long length = RNFetchBlob.RCTContext.getAssets().openFd(assetName).getLength();
bytes = new byte[(int) length];
InputStream in = RNFetchBlob.RCTContext.getAssets().open(assetName);
in.read(bytes, 0, (int) length);
in.close();
}
// issue 287
else if(resolved == null) {
InputStream in = RNFetchBlob.RCTContext.getContentResolver().openInputStream(Uri.parse(path));
int length = (int) in.available();
bytes = new byte[length];
in.read(bytes);
in.close();
}
else {
File f = new File(path);
int length = (int) f.length();
Expand Down Expand Up @@ -226,17 +236,24 @@ static public String getTmpPath(ReactApplicationContext ctx, String taskId) {
* @param bufferSize Buffer size of read stream, default to 4096 (4095 when encode is `base64`)
*/
public void readStream(String path, String encoding, int bufferSize, int tick, final String streamId) {
path = normalizePath(path);
String resolved = normalizePath(path);
if(resolved != null)
path = resolved;
try {

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

InputStream fs;
if(path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
fs = RNFetchBlob.RCTContext.getAssets()
.open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));

if(resolved != null && path.startsWith(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET)) {
fs = RNFetchBlob.RCTContext.getAssets().open(path.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, ""));

}
// fix issue 287
else if(resolved == null) {
fs = RNFetchBlob.RCTContext.getContentResolver().openInputStream(Uri.parse(path));
}
else {
fs = new FileInputStream(new File(path));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public List<NativeModule> createNativeModules(ReactApplicationContext reactConte
return modules;
}

@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
Expand Down
49 changes: 46 additions & 3 deletions android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.util.Base64;

import com.RNFetchBlob.Response.RNFetchBlobDefaultResp;
import com.RNFetchBlob.Response.RNFetchBlobFileResp;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
Expand All @@ -21,6 +23,7 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.modules.network.TLSSocketFactory;

import java.io.File;
import java.io.FileOutputStream;
Expand All @@ -35,11 +38,14 @@
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;

import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.ConnectionPool;
import okhttp3.ConnectionSpec;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
Expand All @@ -48,6 +54,8 @@
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.TlsVersion;


public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {

Expand Down Expand Up @@ -148,8 +156,15 @@ public void run() {
if(options.addAndroidDownloads.hasKey("path")) {
req.setDestinationUri(Uri.parse("file://" + options.addAndroidDownloads.getString("path")));
}
// #391 Add MIME type to the request
if(options.addAndroidDownloads.hasKey("mime")) {
req.setMimeType(options.addAndroidDownloads.getString("mime"));
}
// set headers
ReadableMapKeySetIterator it = headers.keySetIterator();
if(options.addAndroidDownloads.hasKey("mediaScannable") && options.addAndroidDownloads.hasKey("mediaScannable") == true ) {
req.allowScanningByMediaScanner();
}
while (it.hasNextKey()) {
String key = it.nextKey();
req.addRequestHeader(key, headers.getString(key));
Expand Down Expand Up @@ -359,9 +374,10 @@ public Response intercept(Chain chain) throws IOException {
clientBuilder.retryOnConnectionFailure(false);
clientBuilder.followRedirects(options.followRedirect);
clientBuilder.followSslRedirects(options.followRedirect);
clientBuilder.retryOnConnectionFailure(true);

OkHttpClient client = enableTls12OnPreLollipop(clientBuilder).build();

OkHttpClient client = clientBuilder.retryOnConnectionFailure(true).build();
Call call = client.newCall(req);
taskTable.put(taskId, call);
call.enqueue(new okhttp3.Callback() {
Expand Down Expand Up @@ -636,16 +652,20 @@ public void onReceive(Context context, Intent intent) {
return;
}
String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
if (contentUri != null) {
if ( contentUri != null &&
options.addAndroidDownloads.hasKey("mime") &&
options.addAndroidDownloads.getString("mime").contains("image")) {
Uri uri = Uri.parse(contentUri);
Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
// use default destination of DownloadManager

// use default destination of DownloadManager
if (cursor != null) {
cursor.moveToFirst();
filePath = cursor.getString(0);
}
}
}

// When the file is not found in media content database, check if custom path exists
if (options.addAndroidDownloads.hasKey("path")) {
try {
Expand All @@ -672,5 +692,28 @@ public void onReceive(Context context, Intent intent) {
}
}

public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
try {
client.sslSocketFactory(new TLSSocketFactory());

ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();

List< ConnectionSpec > specs = new ArrayList < > ();
specs.add(cs);
specs.add(ConnectionSpec.COMPATIBLE_TLS);
specs.add(ConnectionSpec.CLEARTEXT);

client.connectionSpecs(specs);
} catch (Exception exc) {
FLog.e("OkHttpClientProvider", "Error while enabling TLS 1.2", exc);
}
}

return client;
}


}
22 changes: 18 additions & 4 deletions android/src/main/java/com/RNFetchBlob/Utils/PathResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,16 @@ else if (isMediaDocument(uri)) {

return getDataColumn(context, contentUri, selection, selectionArgs);
}
else if ("content".equalsIgnoreCase(uri.getScheme())) {

// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();

return getDataColumn(context, uri, null, null);
}
// Other Providers
else {
else{
try {
InputStream attachment = context.getContentResolver().openInputStream(uri);
if (attachment != null) {
Expand Down Expand Up @@ -131,6 +139,7 @@ public static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {

Cursor cursor = null;
String result = null;
final String column = "_data";
final String[] projection = {
column
Expand All @@ -141,13 +150,18 @@ public static String getDataColumn(Context context, Uri uri, String selection,
null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
result = cursor.getString(index);
}
} finally {
}
catch (Exception ex) {
ex.printStackTrace();
return null;
}
finally {
if (cursor != null)
cursor.close();
}
return null;
return result;
}


Expand Down
2 changes: 1 addition & 1 deletion ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function openDocument(path:string, fontFamily:string, fontSize: number, hexStrin
* @param {string} url URL of the resource, only file URL is supported
* @return {Promise}
*/
function excludeFromBackupKey(url:string) {
function excludeFromBackupKey(path:string) {
return RNFetchBlob.excludeFromBackupKey('file://' + path);
}

Expand Down
10 changes: 5 additions & 5 deletions ios/RNFetchBlobFS.m
Original file line number Diff line number Diff line change
Expand Up @@ -568,11 +568,11 @@ - (NSString *)openWithPath:(NSString *)destPath encode:(nullable NSString *)enco

// Write file chunk into an opened stream
- (void)writeEncodeChunk:(NSString *) chunk {
NSMutableData * decodedData = [NSData alloc];
NSData * decodedData = nil;
if([[self.encoding lowercaseString] isEqualToString:@"base64"]) {
decodedData = [[NSData alloc] initWithBase64EncodedData:chunk options:0];
}
if([[self.encoding lowercaseString] isEqualToString:@"utf8"]) {
decodedData = [[NSData alloc] initWithBase64EncodedString:chunk options: NSDataBase64DecodingIgnoreUnknownCharacters];
}
else if([[self.encoding lowercaseString] isEqualToString:@"utf8"]) {
decodedData = [chunk dataUsingEncoding:NSUTF8StringEncoding];
}
else if([[self.encoding lowercaseString] isEqualToString:@"ascii"]) {
Expand Down Expand Up @@ -793,4 +793,4 @@ + (void) writeAssetToPath:(ALAssetRepresentation * )rep dest:(NSString *)dest
return;
}

@end
@end
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "react-native-fetch-blob",
"version": "0.10.6",
"version": "0.10.8",
"description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"base-64": "0.1.0",
"glob": "^7.0.6"
"glob": "7.0.6"
},
"keywords": [
"react-native",
Expand All @@ -35,4 +35,4 @@
"Ben <[email protected]>",
""
]
}
}
16 changes: 16 additions & 0 deletions polyfill/Blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ export default class Blob extends EventTarget {
// Blob data from file path
else if(typeof data === 'string' && data.startsWith('RNFetchBlob-file://')) {
log.verbose('create Blob cache file from file path', data)
// set this flag so that we know this blob is a wrapper of an existing file
this._isReference = true
this._ref = String(data).replace('RNFetchBlob-file://', '')
let orgPath = this._ref
if(defer)
Expand Down Expand Up @@ -282,6 +284,20 @@ export default class Blob extends EventTarget {
})
}

safeClose() {
if(this._closed)
return Promise.reject('Blob has been released.')
this._closed = true
if(!this._isReference) {
return fs.unlink(this._ref).catch((err) => {
console.warn(err)
})
}
else {
return Promise.resolve()
}
}

_invokeOnCreateEvent() {
log.verbose('invoke create event', this._onCreated)
this._blobCreated = true
Expand Down
2 changes: 1 addition & 1 deletion polyfill/XMLHttpRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
_headerReceived = (e) => {
log.debug('header received ', this._task.taskId, e)
this.responseURL = this._url
if(e.state === "2") {
if(e.state === "2" && e.taskId === this._task.taskId) {
this._responseHeaders = e.headers
this._statusText = e.status
this._status = Math.floor(e.status)
Expand Down

0 comments on commit 87fcc36

Please sign in to comment.