You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2013/07/16 17:05:42 UTC
git commit: [android] [CB-3384] Make FileTransfer use
CordovaResourceApi.
Updated Branches:
refs/heads/master 616bc344b -> d29f2b044
[android] [CB-3384] Make FileTransfer use CordovaResourceApi.
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/commit/d29f2b04
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/tree/d29f2b04
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/diff/d29f2b04
Branch: refs/heads/master
Commit: d29f2b044b2457ac40e80929ecda143ffeb310f0
Parents: 616bc34
Author: Andrew Grieve <ag...@chromium.org>
Authored: Sat Jul 13 17:18:23 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Jul 16 11:05:34 2013 -0400
----------------------------------------------------------------------
src/android/FileTransfer.java | 169 ++++++++++++++++---------------------
1 file changed, 71 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/d29f2b04/src/android/FileTransfer.java
----------------------------------------------------------------------
diff --git a/src/android/FileTransfer.java b/src/android/FileTransfer.java
index b80e33f..c4b5dd1 100644
--- a/src/android/FileTransfer.java
+++ b/src/android/FileTransfer.java
@@ -22,7 +22,6 @@ import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilterInputStream;
import java.io.IOException;
@@ -31,8 +30,6 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.security.cert.CertificateException;
@@ -53,20 +50,18 @@ import javax.net.ssl.X509TrustManager;
import org.apache.cordova.Config;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.CordovaResourceApi;
+import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
import org.apache.cordova.PluginResult;
-import org.apache.cordova.UriResolver;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-import android.content.ContentResolver;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.webkit.CookieManager;
-import com.squareup.okhttp.OkHttpClient;
-
public class FileTransfer extends CordovaPlugin {
private static final String LOG_TAG = "FileTransfer";
@@ -82,8 +77,6 @@ public class FileTransfer extends CordovaPlugin {
private static HashMap<String, RequestContext> activeRequests = new HashMap<String, RequestContext>();
private static final int MAX_BUFFER_SIZE = 16 * 1024;
- private static OkHttpClient httpClient = new OkHttpClient();
-
private static final class RequestContext {
String source;
String target;
@@ -252,6 +245,8 @@ public class FileTransfer extends CordovaPlugin {
final JSONObject headers = args.optJSONObject(8) == null ? params.optJSONObject("headers") : args.optJSONObject(8);
final String objectId = args.getString(9);
final String httpMethod = getArgument(args, 10, "POST");
+
+ final CordovaResourceApi resourceApi = webView.getResourceApi();
Log.d(LOG_TAG, "fileKey: " + fileKey);
Log.d(LOG_TAG, "fileName: " + fileName);
@@ -263,16 +258,20 @@ public class FileTransfer extends CordovaPlugin {
Log.d(LOG_TAG, "objectId: " + objectId);
Log.d(LOG_TAG, "httpMethod: " + httpMethod);
- final URL url;
- try {
- url = new URL(target);
- } catch (MalformedURLException e) {
+ final Uri targetUri = resourceApi.remapUri(Uri.parse(target));
+ // Accept a path or a URI for the source.
+ Uri tmpSrc = Uri.parse(source);
+ final Uri sourceUri = resourceApi.remapUri(
+ tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));
+
+ int uriType = CordovaResourceApi.getUriType(targetUri);
+ final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
+ if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {
JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
- Log.e(LOG_TAG, error.toString(), e);
+ Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
return;
}
- final boolean useHttps = url.getProtocol().equals("https");
final RequestContext context = new RequestContext(source, target, callbackContext);
synchronized (activeRequests) {
@@ -296,27 +295,15 @@ public class FileTransfer extends CordovaPlugin {
//------------------ CLIENT REQUEST
// Open a HTTP connection to the URL based on protocol
- if (useHttps) {
- // Using standard HTTPS connection. Will not allow self signed certificate
- if (!trustEveryone) {
- conn = (HttpsURLConnection) httpClient.open(url);
- }
- // Use our HTTPS connection that blindly trusts everyone.
- // This should only be used in debug environments
- else {
- // Setup the HTTPS connection class to trust everyone
- HttpsURLConnection https = (HttpsURLConnection) httpClient.open(url);
- oldSocketFactory = trustAllHosts(https);
- // Save the current hostnameVerifier
- oldHostnameVerifier = https.getHostnameVerifier();
- // Setup the connection not to verify hostnames
- https.setHostnameVerifier(DO_NOT_VERIFY);
- conn = https;
- }
- }
- // Return a standard HTTP connection
- else {
- conn = httpClient.open(url);
+ conn = resourceApi.createHttpConnection(targetUri);
+ if (useHttps && trustEveryone) {
+ // Setup the HTTPS connection class to trust everyone
+ HttpsURLConnection https = (HttpsURLConnection)conn;
+ oldSocketFactory = trustAllHosts(https);
+ // Save the current hostnameVerifier
+ oldHostnameVerifier = https.getHostnameVerifier();
+ // Setup the connection not to verify hostnames
+ https.setHostnameVerifier(DO_NOT_VERIFY);
}
// Allow Inputs
@@ -373,11 +360,11 @@ public class FileTransfer extends CordovaPlugin {
// Get a input stream of the file on the phone
- InputStream sourceInputStream = webView.resolveUri(Uri.parse(source)).getInputStream();
+ OpenForReadResult readResult = resourceApi.openForRead(sourceUri);
int stringLength = beforeDataBytes.length + tailParamsBytes.length;
- if (sourceInputStream instanceof FileInputStream) {
- fixedLength = (int) ((FileInputStream)sourceInputStream).getChannel().size() + stringLength;
+ if (readResult.length >= 0) {
+ fixedLength = (int)readResult.length + stringLength;
progress.setLengthComputable(true);
progress.setTotal(fixedLength);
}
@@ -413,12 +400,12 @@ public class FileTransfer extends CordovaPlugin {
totalBytes += beforeDataBytes.length;
// create a buffer of maximum size
- int bytesAvailable = sourceInputStream.available();
+ int bytesAvailable = readResult.inputStream.available();
int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
byte[] buffer = new byte[bufferSize];
// read file and write it into form...
- int bytesRead = sourceInputStream.read(buffer, 0, bufferSize);
+ int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
long prevBytesRead = 0;
while (bytesRead > 0) {
@@ -429,9 +416,9 @@ public class FileTransfer extends CordovaPlugin {
prevBytesRead = totalBytes;
Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
}
- bytesAvailable = sourceInputStream.available();
+ bytesAvailable = readResult.inputStream.available();
bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
- bytesRead = sourceInputStream.read(buffer, 0, bufferSize);
+ bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
// Send a progress event.
progress.setLoaded(totalBytes);
@@ -445,7 +432,7 @@ public class FileTransfer extends CordovaPlugin {
totalBytes += tailParamsBytes.length;
sendStream.flush();
} finally {
- safeClose(sourceInputStream);
+ safeClose(readResult.inputStream);
safeClose(sendStream);
}
context.currentOutputStream = null;
@@ -668,28 +655,30 @@ public class FileTransfer extends CordovaPlugin {
private void download(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
Log.d(LOG_TAG, "download " + source + " to " + target);
+ final CordovaResourceApi resourceApi = webView.getResourceApi();
+
final boolean trustEveryone = args.optBoolean(2);
final String objectId = args.getString(3);
final JSONObject headers = args.optJSONObject(4);
-
- final URL url;
- try {
- url = new URL(source);
- } catch (MalformedURLException e) {
+
+ final Uri sourceUri = resourceApi.remapUri(Uri.parse(source));
+ // Accept a path or a URI for the source.
+ Uri tmpTarget = Uri.parse(target);
+ final Uri targetUri = resourceApi.remapUri(
+ tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));
+
+ int uriType = CordovaResourceApi.getUriType(sourceUri);
+ final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
+ final boolean isLocalTransfer = !useHttps && uriType != CordovaResourceApi.URI_TYPE_HTTP;
+ if (uriType == CordovaResourceApi.URI_TYPE_UNKNOWN) {
JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
- Log.e(LOG_TAG, error.toString(), e);
+ Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
return;
}
- final String sourceProtocol = url.getProtocol();
- final boolean useHttps = "https".equals(sourceProtocol);
- final boolean useResolvers =
- ContentResolver.SCHEME_FILE.equals(sourceProtocol) ||
- ContentResolver.SCHEME_CONTENT.equals(sourceProtocol) ||
- ContentResolver.SCHEME_ANDROID_RESOURCE.equals(sourceProtocol);
-
+
// TODO: refactor to also allow resources & content:
- if (!useResolvers && !Config.isUrlWhiteListed(source)) {
+ if (!isLocalTransfer && !Config.isUrlWhiteListed(source)) {
Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401);
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
@@ -707,64 +696,50 @@ public class FileTransfer extends CordovaPlugin {
if (context.aborted) {
return;
}
- URLConnection connection = null;
+ HttpURLConnection connection = null;
HostnameVerifier oldHostnameVerifier = null;
SSLSocketFactory oldSocketFactory = null;
File file = null;
PluginResult result = null;
TrackingInputStream inputStream = null;
+ OutputStream outputStream = null;
try {
- UriResolver sourceResolver = null;
- UriResolver targetResolver = webView.resolveUri(Uri.parse(target));
+ OpenForReadResult readResult = null;
+ outputStream = resourceApi.openOutputStream(targetUri);
- file = targetResolver.getLocalFile();
+ file = resourceApi.mapUriToFile(targetUri);
context.targetFile = file;
- Log.d(LOG_TAG, "Download file:" + url);
+ Log.d(LOG_TAG, "Download file:" + sourceUri);
FileProgressResult progress = new FileProgressResult();
- if (useResolvers) {
- sourceResolver = webView.resolveUri(Uri.parse(source));
- long len = sourceResolver.computeLength();
- if (len != -1) {
+ if (isLocalTransfer) {
+ readResult = resourceApi.openForRead(sourceUri);
+ if (readResult.length != -1) {
progress.setLengthComputable(true);
- progress.setTotal(len);
+ progress.setTotal(readResult.length);
}
- inputStream = new SimpleTrackingInputStream(sourceResolver.getInputStream());
+ inputStream = new SimpleTrackingInputStream(readResult.inputStream);
} else {
// connect to server
// Open a HTTP connection to the URL based on protocol
- if (useHttps) {
- // Using standard HTTPS connection. Will not allow self signed certificate
- if (!trustEveryone) {
- connection = (HttpsURLConnection) httpClient.open(url);
- }
- // Use our HTTPS connection that blindly trusts everyone.
- // This should only be used in debug environments
- else {
- // Setup the HTTPS connection class to trust everyone
- HttpsURLConnection https = (HttpsURLConnection) httpClient.open(url);
- oldSocketFactory = trustAllHosts(https);
- // Save the current hostnameVerifier
- oldHostnameVerifier = https.getHostnameVerifier();
- // Setup the connection not to verify hostnames
- https.setHostnameVerifier(DO_NOT_VERIFY);
- connection = https;
- }
- }
- // Return a standard HTTP connection
- else {
- connection = httpClient.open(url);
+ connection = resourceApi.createHttpConnection(sourceUri);
+ if (useHttps && trustEveryone) {
+ // Setup the HTTPS connection class to trust everyone
+ HttpsURLConnection https = (HttpsURLConnection)connection;
+ oldSocketFactory = trustAllHosts(https);
+ // Save the current hostnameVerifier
+ oldHostnameVerifier = https.getHostnameVerifier();
+ // Setup the connection not to verify hostnames
+ https.setHostnameVerifier(DO_NOT_VERIFY);
}
- if (connection instanceof HttpURLConnection) {
- ((HttpURLConnection)connection).setRequestMethod("GET");
- }
+ connection.setRequestMethod("GET");
- //Add cookie support
- String cookie = CookieManager.getInstance().getCookie(source);
+ // TODO: Make OkHttp use this CookieManager by default.
+ String cookie = CookieManager.getInstance().getCookie(sourceUri.toString());
if(cookie != null)
{
connection.setRequestProperty("cookie", cookie);
@@ -789,10 +764,7 @@ public class FileTransfer extends CordovaPlugin {
inputStream = getInputStream(connection);
}
- OutputStream outputStream = null;
-
try {
- outputStream = targetResolver.getOutputStream();
synchronized (context) {
if (context.aborted) {
return;
@@ -839,6 +811,7 @@ public class FileTransfer extends CordovaPlugin {
Log.e(LOG_TAG, error.toString(), e);
result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
} finally {
+ safeClose(outputStream);
synchronized (activeRequests) {
activeRequests.remove(objectId);
}