cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] maverickmishra closed pull request #190: [Android] Handle redirects when downloading a file (actual)
Date Thu, 01 Jan 1970 00:00:00 GMT
maverickmishra closed pull request #190: [Android] Handle redirects when downloading a file
(actual)
URL: https://github.com/apache/cordova-plugin-file-transfer/pull/190
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/src/android/FileTransfer.java b/src/android/FileTransfer.java
index 5a3c5d6..a846d04 100644
--- a/src/android/FileTransfer.java
+++ b/src/android/FileTransfer.java
@@ -32,12 +32,24 @@ Licensed to the Apache Software Foundation (ASF) under one
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.net.HttpURLConnection;
+import java.net.URL;
 import java.net.URLConnection;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.Inflater;
 
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+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;
@@ -273,6 +285,7 @@ private void upload(final String source, final String target, JSONArray
args, Ca
         final String fileName = getArgument(args, 3, "image.jpg");
         final String mimeType = getArgument(args, 4, "image/jpeg");
         final JSONObject params = args.optJSONObject(5) == null ? new JSONObject() : args.optJSONObject(5);
+        final boolean trustEveryone = args.optBoolean(6);
         // Always use chunked mode unless set to false as per API
         final boolean chunkedMode = args.optBoolean(7) || args.isNull(7);
         // Look for headers on the params map for backwards compatibility with older Cordova
versions.
@@ -286,12 +299,17 @@ private void upload(final String source, final String target, JSONArray
args, Ca
         LOG.d(LOG_TAG, "fileName: " + fileName);
         LOG.d(LOG_TAG, "mimeType: " + mimeType);
         LOG.d(LOG_TAG, "params: " + params);
+        LOG.d(LOG_TAG, "trustEveryone: " + trustEveryone);
         LOG.d(LOG_TAG, "chunkedMode: " + chunkedMode);
         LOG.d(LOG_TAG, "headers: " + headers);
         LOG.d(LOG_TAG, "objectId: " + objectId);
         LOG.d(LOG_TAG, "httpMethod: " + httpMethod);
 
         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;
@@ -321,6 +339,8 @@ public void run() {
                         tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));
 
                 HttpURLConnection conn = null;
+                HostnameVerifier oldHostnameVerifier = null;
+                SSLSocketFactory oldSocketFactory = null;
                 int totalBytes = 0;
                 int fixedLength = -1;
                 try {
@@ -331,6 +351,15 @@ public void run() {
                     //------------------ CLIENT REQUEST
                     // Open a HTTP connection to the URL based on protocol
                     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
                     conn.setDoInput(true);
@@ -542,6 +571,15 @@ public void run() {
                     synchronized (activeRequests) {
                         activeRequests.remove(objectId);
                     }
+
+                    if (conn != null) {
+                        // Revert back to the proper verifier and socket factories
+                        if (trustEveryone && useHttps) {
+                            HttpsURLConnection https = (HttpsURLConnection) conn;
+                            https.setHostnameVerifier(oldHostnameVerifier);
+                            https.setSSLSocketFactory(oldSocketFactory);
+                        }
+                    }
                 }
             }
         });
@@ -564,6 +602,50 @@ private static TrackingInputStream getInputStream(URLConnection conn)
throws IOE
         return new SimpleTrackingInputStream(conn.getInputStream());
     }
 
+    // always verify the host - don't check for certificate
+    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
+        public boolean verify(String hostname, SSLSession session) {
+            return true;
+        }
+    };
+    // Create a trust manager that does not validate certificate chains
+    private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+            return new java.security.cert.X509Certificate[] {};
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain,
+                String authType) throws CertificateException {
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain,
+                String authType) throws CertificateException {
+        }
+    } };
+
+    /**
+     * This function will install a trust manager that will blindly trust all SSL
+     * certificates.  The reason this code is being added is to enable developers
+     * to do development using self signed SSL certificates on their web server.
+     *
+     * The standard HttpsURLConnection class will throw an exception on self
+     * signed certificates if this code is not run.
+     */
+    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {
+        // Install the all-trusting trust manager
+        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();
+        try {
+            // Install our all trusting manager
+            SSLContext sc = SSLContext.getInstance("TLS");
+            sc.init(null, trustAllCerts, new java.security.SecureRandom());
+            SSLSocketFactory newFactory = sc.getSocketFactory();
+            connection.setSSLSocketFactory(newFactory);
+        } catch (Exception e) {
+            LOG.e(LOG_TAG, e.getMessage(), e);
+        }
+        return oldFactory;
+    }
+
     private static JSONObject createFileTransferError(int errorCode, String source, String
target, URLConnection connection, Throwable throwable) {
 
         int httpStatus = 0;
@@ -662,10 +744,16 @@ private void download(final String source, final String target, JSONArray
args,
 
         final CordovaResourceApi resourceApi = webView.getResourceApi();
 
+        final boolean trustEveryone = args.optBoolean(2);
         final String objectId = args.getString(3);
         final JSONObject headers = args.optJSONObject(4);
 
         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;
@@ -731,6 +819,8 @@ public void run() {
                 Uri targetUri = resourceApi.remapUri(
                         tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));
                 HttpURLConnection connection = null;
+                HostnameVerifier oldHostnameVerifier = null;
+                SSLSocketFactory oldSocketFactory = null;
                 File file = null;
                 PluginResult result = null;
                 TrackingInputStream inputStream = null;
@@ -755,28 +845,53 @@ public void run() {
                         }
                         inputStream = new SimpleTrackingInputStream(readResult.inputStream);
                     } else {
-                        // connect to server
-                        // Open a HTTP connection to the URL based on protocol
-                        connection = resourceApi.createHttpConnection(sourceUri);
-                        connection.setRequestMethod("GET");
-
-                        // TODO: Make OkHttp use this CookieManager by default.
-                        String cookie = getCookies(sourceUri.toString());
-
-                        if(cookie != null)
+						Uri currentSourceUri = sourceUri;
+                        while (true)
                         {
-                            connection.setRequestProperty("cookie", cookie);
-                        }
-
-                        // This must be explicitly set for gzip progress tracking to work.
-                        connection.setRequestProperty("Accept-Encoding", "gzip");
-
-                        // Handle the other headers
-                        if (headers != null) {
-                            addHeadersToRequest(connection, headers);
-                        }
+	                        // connect to server
+	                        // Open a HTTP connection to the URL based on protocol
+	                        connection = resourceApi.createHttpConnection(currentSourceUri);
+	                        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);
+	                        }
+	
+	                        connection.setRequestMethod("GET");
+
+	                        // TODO: Make OkHttp use this CookieManager by default.
+	                        String cookie = getCookies(currentSourceUri.toString());
+	
+	                        if(cookie != null)
+	                        {
+	                            connection.setRequestProperty("cookie", cookie);
+	                        }
+	
+	                        // This must be explicitly set for gzip progress tracking to work.
+	                        connection.setRequestProperty("Accept-Encoding", "gzip");
+
+	                        // Handle the other headers
+	                        if (headers != null) {
+	                            addHeadersToRequest(connection, headers);
+	                        }
+	
+	                        connection.connect();
+
+                            if (connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM
||
+                                connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP)
{
+                                String location = connection.getHeaderField("Location");
+                                URL base  = new URL(currentSourceUri.toString());
+                                URL next  = new URL(base, location);  // Deal with relative
URLs
+                                currentSourceUri = Uri.parse(next.toString());
+                                continue;
+                            }
+	                        break;
+						}
 
-                        connection.connect();
                         if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED)
{
                             cached = true;
                             connection.disconnect();
@@ -883,6 +998,15 @@ public void run() {
                         activeRequests.remove(objectId);
                     }
 
+                    if (connection != null) {
+                        // Revert back to the proper verifier and socket factories
+                        if (trustEveryone && useHttps) {
+                            HttpsURLConnection https = (HttpsURLConnection) connection;
+                            https.setHostnameVerifier(oldHostnameVerifier);
+                            https.setSSLSocketFactory(oldSocketFactory);
+                        }
+                    }
+
                     if (result == null) {
                         result = new PluginResult(PluginResult.Status.ERROR, createFileTransferError(CONNECTION_ERR,
source, target, connection, null));
                     }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message