List of usage examples for javax.net.ssl HttpsURLConnection getHostnameVerifier
public HostnameVerifier getHostnameVerifier()
HostnameVerifier
in place on this instance. From source file:com.phonegap.FileTransfer.java
/** * Uploads the specified file to the server URL provided using an HTTP * multipart request. /*from w ww.j a va 2 s. co m*/ * @param file Full path of the file on the file system * @param server URL of the server to receive the file * @param fileKey Name of file request parameter * @param fileName File name to be used on server * @param mimeType Describes file content type * @param params key:value pairs of user-defined parameters * @return FileUploadResult containing result of upload request */ public FileUploadResult upload(String file, String server, final String fileKey, final String fileName, final String mimeType, JSONObject params, boolean trustEveryone) throws IOException, SSLException { // Create return object FileUploadResult result = new FileUploadResult(); // Get a input stream of the file on the phone InputStream fileInputStream = getPathFromUri(file); HttpURLConnection conn = null; DataOutputStream dos = null; int bytesRead, bytesAvailable, bufferSize; long totalBytes; byte[] buffer; int maxBufferSize = 8096; //------------------ CLIENT REQUEST // open a URL connection to the server URL url = new URL(server); // Open a HTTP connection to the URL based on protocol if (url.getProtocol().toLowerCase().equals("https")) { // Using standard HTTPS connection. Will not allow self signed certificate if (!trustEveryone) { conn = (HttpsURLConnection) url.openConnection(); } // 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 trustAllHosts(); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); // Save the current hostnameVerifier defaultHostnameVerifier = https.getHostnameVerifier(); // Setup the connection not to verify hostnames https.setHostnameVerifier(DO_NOT_VERIFY); conn = https; } } // Return a standard HTTP conneciton else { conn = (HttpURLConnection) url.openConnection(); } // Allow Inputs conn.setDoInput(true); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDRY); // Set the cookies on the response String cookie = CookieManager.getInstance().getCookie(server); if (cookie != null) { conn.setRequestProperty("Cookie", cookie); } dos = new DataOutputStream(conn.getOutputStream()); // Send any extra parameters try { for (Iterator iter = params.keys(); iter.hasNext();) { Object key = iter.next(); dos.writeBytes(LINE_START + BOUNDRY + LINE_END); dos.writeBytes("Content-Disposition: form-data; name=\"" + key.toString() + "\"; "); dos.writeBytes(LINE_END + LINE_END); dos.writeBytes(params.getString(key.toString())); dos.writeBytes(LINE_END); } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } dos.writeBytes(LINE_START + BOUNDRY + LINE_END); dos.writeBytes("Content-Disposition: form-data; name=\"" + fileKey + "\";" + " filename=\"" + fileName + "\"" + LINE_END); dos.writeBytes("Content-Type: " + mimeType + LINE_END); dos.writeBytes(LINE_END); // create a buffer of maximum size bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; // read file and write it into form... bytesRead = fileInputStream.read(buffer, 0, bufferSize); totalBytes = 0; while (bytesRead > 0) { totalBytes += bytesRead; result.setBytesSent(totalBytes); dos.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } // send multipart form data necesssary after file data... dos.writeBytes(LINE_END); dos.writeBytes(LINE_START + BOUNDRY + LINE_START + LINE_END); // close streams fileInputStream.close(); dos.flush(); dos.close(); //------------------ read the SERVER RESPONSE StringBuffer responseString = new StringBuffer(""); DataInputStream inStream = new DataInputStream(conn.getInputStream()); String line; while ((line = inStream.readLine()) != null) { responseString.append(line); } Log.d(LOG_TAG, "got response from server"); Log.d(LOG_TAG, responseString.toString()); // send request and retrieve response result.setResponseCode(conn.getResponseCode()); result.setResponse(responseString.toString()); inStream.close(); conn.disconnect(); // Revert back to the proper verifier and socket factories if (trustEveryone && url.getProtocol().toLowerCase().equals("https")) { ((HttpsURLConnection) conn).setHostnameVerifier(defaultHostnameVerifier); HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSocketFactory); } return result; }
From source file:com.polyvi.xface.extension.filetransfer.XFileTransferExt.java
/** * ?Http//from www. j a v a 2 s.com * @param url ?? * @param trustEveryone */ private HttpURLConnection getURLConnection(URL url, boolean trustEveryone) throws IOException { HttpURLConnection conn = null; // ?URL??HTTP if (url.getProtocol().toLowerCase().equals("https")) { // HTTPS. ???? if (!trustEveryone) { conn = (HttpsURLConnection) url.openConnection(); } else { trustAllHosts(); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); // ?? hostnameVerifier mDefaultHostnameVerifier = https.getHostnameVerifier(); https.setHostnameVerifier(DO_NOT_VERIFY); conn = https; } } // HTTP else { conn = (HttpURLConnection) url.openConnection(); } return conn; }
From source file:org.skt.runtime.html5apis.file.FileTransfer.java
/** * Uploads the specified file to the server URL provided using an HTTP multipart request. * @param source Full path of the file on the file system * @param target URL of the server to receive the file * @param args JSON Array of args * * args[2] fileKey Name of file request parameter * args[3] fileName File name to be used on server * args[4] mimeType Describes file content type * args[5] params key:value pairs of user-defined parameters * @return FileUploadResult containing result of upload request *//*from w w w.j a v a 2s .co m*/ private PluginResult upload(String source, String target, JSONArray args) { Log.d(LOG_TAG, "upload " + source + " to " + target); HttpURLConnection conn = null; try { // Setup the options String fileKey = getArgument(args, 2, "file"); String fileName = getArgument(args, 3, "image.jpg"); String mimeType = getArgument(args, 4, "image/jpeg"); JSONObject params = args.optJSONObject(5); if (params == null) { params = new JSONObject(); } boolean trustEveryone = args.optBoolean(6); boolean chunkedMode = args.optBoolean(7) || args.isNull(7); //Always use chunked mode unless set to false as per API Log.d(LOG_TAG, "fileKey: " + fileKey); 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); // Create return object FileUploadResult result = new FileUploadResult(); // Get a input stream of the file on the phone FileInputStream fileInputStream = (FileInputStream) getPathFromUri(source); DataOutputStream dos = null; int bytesRead, bytesAvailable, bufferSize; long totalBytes; byte[] buffer; int maxBufferSize = 8096; //------------------ CLIENT REQUEST // open a URL connection to the server URL url = new URL(target); // Open a HTTP connection to the URL based on protocol if (url.getProtocol().toLowerCase().equals("https")) { // Using standard HTTPS connection. Will not allow self signed certificate if (!trustEveryone) { conn = (HttpsURLConnection) url.openConnection(); } // 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 trustAllHosts(); HttpsURLConnection https = (HttpsURLConnection) url.openConnection(); // Save the current hostnameVerifier defaultHostnameVerifier = https.getHostnameVerifier(); // Setup the connection not to verify hostnames https.setHostnameVerifier(DO_NOT_VERIFY); conn = https; } } // Return a standard HTTP connection else { conn = (HttpURLConnection) url.openConnection(); } // Allow Inputs conn.setDoInput(true); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); // Handle the other headers try { JSONObject headers = params.getJSONObject("headers"); for (Iterator iter = headers.keys(); iter.hasNext();) { String headerKey = iter.next().toString(); conn.setRequestProperty(headerKey, headers.getString(headerKey)); } } catch (JSONException e1) { // No headers to be manipulated! } // Set the cookies on the response String cookie = CookieManager.getInstance().getCookie(target); if (cookie != null) { conn.setRequestProperty("Cookie", cookie); } /* * Store the non-file portions of the multipart data as a string, so that we can add it * to the contentSize, since it is part of the body of the HTTP request. */ String extraParams = ""; try { for (Iterator iter = params.keys(); iter.hasNext();) { Object key = iter.next(); if (!String.valueOf(key).equals("headers")) { extraParams += LINE_START + BOUNDARY + LINE_END; extraParams += "Content-Disposition: form-data; name=\"" + key.toString() + "\";"; extraParams += LINE_END + LINE_END; extraParams += params.getString(key.toString()); extraParams += LINE_END; } } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } extraParams += LINE_START + BOUNDARY + LINE_END; extraParams += "Content-Disposition: form-data; name=\"" + fileKey + "\";" + " filename=\""; String midParams = "\"" + LINE_END + "Content-Type: " + mimeType + LINE_END + LINE_END; String tailParams = LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END; // Should set this up as an option if (chunkedMode) { conn.setChunkedStreamingMode(maxBufferSize); } else { int stringLength = extraParams.getBytes("UTF-8").length + midParams.getBytes("UTF-8").length + tailParams.getBytes("UTF-8").length + fileName.getBytes("UTF-8").length; Log.d(LOG_TAG, "String Length: " + stringLength); int fixedLength = (int) fileInputStream.getChannel().size() + stringLength; Log.d(LOG_TAG, "Content Length: " + fixedLength); conn.setFixedLengthStreamingMode(fixedLength); } dos = new DataOutputStream(conn.getOutputStream()); dos.write(extraParams.getBytes("UTF-8")); //We don't want to chagne encoding, we just want this to write for all Unicode. dos.write(fileName.getBytes("UTF-8")); dos.write(midParams.getBytes("UTF-8")); // create a buffer of maximum size bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); buffer = new byte[bufferSize]; // read file and write it into form... bytesRead = fileInputStream.read(buffer, 0, bufferSize); totalBytes = 0; while (bytesRead > 0) { totalBytes += bytesRead; result.setBytesSent(totalBytes); dos.write(buffer, 0, bufferSize); bytesAvailable = fileInputStream.available(); bufferSize = Math.min(bytesAvailable, maxBufferSize); bytesRead = fileInputStream.read(buffer, 0, bufferSize); } // send multipart form data necesssary after file data... dos.write(tailParams.getBytes("UTF-8")); // close streams fileInputStream.close(); dos.flush(); dos.close(); //------------------ read the SERVER RESPONSE StringBuffer responseString = new StringBuffer(""); DataInputStream inStream; try { inStream = new DataInputStream(conn.getInputStream()); } catch (FileNotFoundException e) { Log.e(LOG_TAG, e.toString(), e); throw new IOException("Received error from server"); } String line; while ((line = inStream.readLine()) != null) { responseString.append(line); } Log.d(LOG_TAG, "got response from server"); Log.d(LOG_TAG, responseString.toString()); // send request and retrieve response result.setResponseCode(conn.getResponseCode()); result.setResponse(responseString.toString()); inStream.close(); // Revert back to the proper verifier and socket factories if (trustEveryone && url.getProtocol().toLowerCase().equals("https")) { ((HttpsURLConnection) conn).setHostnameVerifier(defaultHostnameVerifier); HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSocketFactory); } Log.d(LOG_TAG, "****** About to return a result from upload"); return new PluginResult(PluginResult.Status.OK, result.toJSONObject()); } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); return new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (MalformedURLException e) { JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); return new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); return new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); return new PluginResult(PluginResult.Status.JSON_EXCEPTION); } catch (Throwable t) { // Shouldn't happen, but will JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.wtf(LOG_TAG, error.toString(), t); return new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } finally { if (conn != null) { conn.disconnect(); } } }
From source file:com.percolatestudio.cordova.fileupload.PSFileUpload.java
/** * Uploads the specified file to the server URL provided using an HTTP multipart request. * @param source Full path of the file on the file system * @param target URL of the server to receive the file * @param args JSON Array of args * @param callbackContext callback id for optional progress reports * * args[2] fileKey Name of file request parameter * args[3] fileName File name to be used on server * args[4] mimeType Describes file content type * args[5] params key:value pairs of user-defined parameters * @return FileUploadResult containing result of upload request *///from ww w.j a v a2s. com private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException { Log.d(LOG_TAG, "upload " + source + " to " + target); // Setup the options 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. 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, "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; if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) { JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0); Log.e(LOG_TAG, "Unsupported URI: " + targetUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection conn = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; int totalBytes = 0; int fixedLength = -1; try { // Create return object PSFileUploadResult result = new PSFileUploadResult(); PSFileProgressResult progress = new PSFileProgressResult(); //------------------ 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); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod(httpMethod); conn.setRequestProperty("Content-Type", mimeType); // Set the cookies on the response String cookie = CookieManager.getInstance().getCookie(target); if (cookie != null) { conn.setRequestProperty("Cookie", cookie); } // Handle the other headers if (headers != null) { addHeadersToRequest(conn, headers); } // Get a input stream of the file on the phone OpenForReadResult readResult = resourceApi.openForRead(sourceUri); if (readResult.length >= 0) { fixedLength = (int) readResult.length; progress.setLengthComputable(true); progress.setTotal(fixedLength); } Log.d(LOG_TAG, "Content Length: " + fixedLength); // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices. // http://code.google.com/p/android/issues/detail?id=3164 // It also causes OOM if HTTPS is used, even on newer devices. boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps); useChunkedMode = useChunkedMode || (fixedLength == -1); if (useChunkedMode) { conn.setChunkedStreamingMode(MAX_BUFFER_SIZE); // Although setChunkedStreamingMode sets this header, setting it explicitly here works // around an OutOfMemoryException when using https. conn.setRequestProperty("Transfer-Encoding", "chunked"); } else { conn.setFixedLengthStreamingMode(fixedLength); } conn.connect(); OutputStream sendStream = null; try { sendStream = conn.getOutputStream(); synchronized (context) { if (context.aborted) { return; } context.currentOutputStream = sendStream; } //We don't want to change encoding, we just want this to write for all Unicode. // create a buffer of maximum size 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 = readResult.inputStream.read(buffer, 0, bufferSize); long prevBytesRead = 0; while (bytesRead > 0) { result.setBytesSent(totalBytes); sendStream.write(buffer, 0, bytesRead); totalBytes += bytesRead; if (totalBytes > prevBytesRead + 102400) { prevBytesRead = totalBytes; Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes"); } bytesAvailable = readResult.inputStream.available(); bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE); bytesRead = readResult.inputStream.read(buffer, 0, bufferSize); // Send a progress event. progress.setLoaded(totalBytes); PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject()); progressResult.setKeepCallback(true); context.sendPluginResult(progressResult); } sendStream.flush(); } finally { safeClose(readResult.inputStream); safeClose(sendStream); } context.currentOutputStream = null; Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength); //------------------ read the SERVER RESPONSE String responseString; int responseCode = conn.getResponseCode(); Log.d(LOG_TAG, "response code: " + responseCode); Log.d(LOG_TAG, "response headers: " + conn.getHeaderFields()); TrackingInputStream inStream = null; try { inStream = getInputStream(conn); synchronized (context) { if (context.aborted) { return; } context.currentInputStream = inStream; } ByteArrayOutputStream out = new ByteArrayOutputStream( Math.max(1024, conn.getContentLength())); byte[] buffer = new byte[1024]; int bytesRead = 0; // write bytes to file while ((bytesRead = inStream.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); } responseString = out.toString("UTF-8"); } finally { context.currentInputStream = null; safeClose(inStream); } Log.d(LOG_TAG, "got response from server"); Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length()))); // send request and retrieve response result.setResponseCode(responseCode); result.setResponse(responseString); context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject())); } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes."); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); } catch (Throwable t) { // Shouldn't happen, but will JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), t); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } finally { synchronized (activeRequests) { activeRequests.remove(objectId); } if (conn != null) { // Revert back to the proper verifier and socket factories // Revert back to the proper verifier and socket factories if (trustEveryone && useHttps) { HttpsURLConnection https = (HttpsURLConnection) conn; https.setHostnameVerifier(oldHostnameVerifier); https.setSSLSocketFactory(oldSocketFactory); } } } } }); }
From source file:org.apache.cordova.core.FileTransfer.java
/** * Downloads a file form a given URL and saves it to the specified directory. * * @param source URL of the server to receive the file * @param target Full path of the file on the file system *//*from ww w. ja v a 2 s . co m*/ 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 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, "Unsupported URI: " + targetUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } // TODO: refactor to also allow resources & content: 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)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection connection = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; File file = null; PluginResult result = null; TrackingInputStream inputStream = null; OutputStream outputStream = null; try { OpenForReadResult readResult = null; outputStream = resourceApi.openOutputStream(targetUri); file = resourceApi.mapUriToFile(targetUri); context.targetFile = file; Log.d(LOG_TAG, "Download file:" + sourceUri); FileProgressResult progress = new FileProgressResult(); if (isLocalTransfer) { readResult = resourceApi.openForRead(sourceUri); if (readResult.length != -1) { progress.setLengthComputable(true); progress.setTotal(readResult.length); } inputStream = new SimpleTrackingInputStream(readResult.inputStream); } else { // connect to server // Open a HTTP connection to the URL based on protocol 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); } connection.setRequestMethod("GET"); // TODO: Make OkHttp use this CookieManager by default. String cookie = CookieManager.getInstance().getCookie(sourceUri.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.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) { // Only trust content-length header if we understand // the encoding -- identity or gzip progress.setLengthComputable(true); progress.setTotal(connection.getContentLength()); } inputStream = getInputStream(connection); } try { synchronized (context) { if (context.aborted) { return; } context.currentInputStream = inputStream; } // write bytes to file byte[] buffer = new byte[MAX_BUFFER_SIZE]; int bytesRead = 0; while ((bytesRead = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, bytesRead); // Send a progress event. progress.setLoaded(inputStream.getTotalRawBytesRead()); PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject()); progressResult.setKeepCallback(true); context.sendPluginResult(progressResult); } } finally { context.currentInputStream = null; safeClose(inputStream); safeClose(outputStream); } Log.d(LOG_TAG, "Saved file: " + target); // create FileEntry object JSONObject fileEntry = FileUtils.getEntry(file); result = new PluginResult(PluginResult.Status.OK, fileEntry); } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); result = new PluginResult(PluginResult.Status.JSON_EXCEPTION); } catch (Throwable e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } finally { safeClose(outputStream); synchronized (activeRequests) { 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)); } // Remove incomplete download. if (result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) { file.delete(); } context.sendPluginResult(result); } } }); }
From source file:com.remobile.filetransfer.FileTransfer.java
/** * Downloads a file form a given URL and saves it to the specified directory. * * @param source URL of the server to receive the file * @param target Full path of the file on the file system *//*from ww w . ja v a 2 s .c om*/ 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 = new CordovaResourceApi(getReactApplicationContext()); 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; if (uriType == CordovaResourceApi.URI_TYPE_UNKNOWN) { JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null); Log.e(LOG_TAG, "Unsupported URI: " + sourceUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } this.cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection connection = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; File file = null; PluginResult result = null; TrackingInputStream inputStream = null; boolean cached = false; OutputStream outputStream = null; try { CordovaResourceApi.OpenForReadResult readResult = null; file = resourceApi.mapUriToFile(targetUri); context.targetFile = file; Log.d(LOG_TAG, "Download file:" + sourceUri); FileProgressResult progress = new FileProgressResult(); if (isLocalTransfer) { readResult = resourceApi.openForRead(sourceUri); if (readResult.length != -1) { progress.setLengthComputable(true); progress.setTotal(readResult.length); } inputStream = new SimpleTrackingInputStream(readResult.inputStream); } else { // connect to server // Open a HTTP connection to the URL based on protocol 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); } connection.setRequestMethod("GET"); // 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_NOT_MODIFIED) { cached = true; connection.disconnect(); Log.d(LOG_TAG, "Resource not modified: " + source); JSONObject error = createFileTransferError(NOT_MODIFIED_ERR, source, target, connection, null); result = new PluginResult(PluginResult.Status.ERROR, error); } else { if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) { // Only trust content-length header if we understand // the encoding -- identity or gzip if (connection.getContentLength() != -1) { progress.setLengthComputable(true); progress.setTotal(connection.getContentLength()); } } inputStream = getInputStream(connection); } } if (!cached) { try { synchronized (context) { if (context.aborted) { return; } context.connection = connection; } // write bytes to file byte[] buffer = new byte[MAX_BUFFER_SIZE]; int bytesRead = 0; outputStream = resourceApi.openOutputStream(targetUri); while ((bytesRead = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, bytesRead); // Send a progress event. progress.setLoaded(inputStream.getTotalRawBytesRead()); FileTransfer.this.sendJSEvent("DownloadProgress-" + objectId, JsonConvert.jsonToReact(progress.toJSONObject())); } } finally { synchronized (context) { context.connection = null; } safeClose(inputStream); safeClose(outputStream); } Log.d(LOG_TAG, "Saved file: " + target); file = resourceApi.mapUriToFile(targetUri); context.targetFile = file; result = new PluginResult(PluginResult.Status.OK, targetUri.getPath()); } } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); result = new PluginResult(PluginResult.Status.JSON_EXCEPTION); } catch (Throwable e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } finally { synchronized (activeRequests) { 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)); } // Remove incomplete download. if (!cached && result.status.ordinal() != PluginResult.Status.OK.ordinal() && file != null) { file.delete(); } context.sendPluginResult(result); } } }); }
From source file:org.apache.cordova.core.FileTransfer.java
/** * Uploads the specified file to the server URL provided using an HTTP multipart request. * @param source Full path of the file on the file system * @param target URL of the server to receive the file * @param args JSON Array of args * @param callbackContext callback id for optional progress reports * * args[2] fileKey Name of file request parameter * args[3] fileName File name to be used on server * args[4] mimeType Describes file content type * args[5] params key:value pairs of user-defined parameters * @return FileUploadResult containing result of upload request *///from www. j a v a 2 s . c om private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException { Log.d(LOG_TAG, "upload " + source + " to " + target); // Setup the options final String fileKey = getArgument(args, 2, "file"); 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. 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); 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; if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) { JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0); Log.e(LOG_TAG, "Unsupported URI: " + targetUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection conn = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; int totalBytes = 0; int fixedLength = -1; try { // Create return object FileUploadResult result = new FileUploadResult(); FileProgressResult progress = new FileProgressResult(); //------------------ 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); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod(httpMethod); conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); // Set the cookies on the response String cookie = CookieManager.getInstance().getCookie(target); if (cookie != null) { conn.setRequestProperty("Cookie", cookie); } // Handle the other headers if (headers != null) { addHeadersToRequest(conn, headers); } /* * Store the non-file portions of the multipart data as a string, so that we can add it * to the contentSize, since it is part of the body of the HTTP request. */ StringBuilder beforeData = new StringBuilder(); try { for (Iterator<?> iter = params.keys(); iter.hasNext();) { Object key = iter.next(); if (!String.valueOf(key).equals("headers")) { beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END); beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()) .append('"'); beforeData.append(LINE_END).append(LINE_END); beforeData.append(params.getString(key.toString())); beforeData.append(LINE_END); } } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END); beforeData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";"); beforeData.append(" filename=\"").append(fileName).append('"').append(LINE_END); beforeData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END); byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8"); byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END) .getBytes("UTF-8"); // Get a input stream of the file on the phone OpenForReadResult readResult = resourceApi.openForRead(sourceUri); int stringLength = beforeDataBytes.length + tailParamsBytes.length; if (readResult.length >= 0) { fixedLength = (int) readResult.length + stringLength; progress.setLengthComputable(true); progress.setTotal(fixedLength); } Log.d(LOG_TAG, "Content Length: " + fixedLength); // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices. // http://code.google.com/p/android/issues/detail?id=3164 // It also causes OOM if HTTPS is used, even on newer devices. boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps); useChunkedMode = useChunkedMode || (fixedLength == -1); if (useChunkedMode) { conn.setChunkedStreamingMode(MAX_BUFFER_SIZE); // Although setChunkedStreamingMode sets this header, setting it explicitly here works // around an OutOfMemoryException when using https. conn.setRequestProperty("Transfer-Encoding", "chunked"); } else { conn.setFixedLengthStreamingMode(fixedLength); } conn.connect(); OutputStream sendStream = null; try { sendStream = conn.getOutputStream(); synchronized (context) { if (context.aborted) { return; } context.currentOutputStream = sendStream; } //We don't want to change encoding, we just want this to write for all Unicode. sendStream.write(beforeDataBytes); totalBytes += beforeDataBytes.length; // create a buffer of maximum size 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 = readResult.inputStream.read(buffer, 0, bufferSize); long prevBytesRead = 0; while (bytesRead > 0) { result.setBytesSent(totalBytes); sendStream.write(buffer, 0, bytesRead); totalBytes += bytesRead; if (totalBytes > prevBytesRead + 102400) { prevBytesRead = totalBytes; Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes"); } bytesAvailable = readResult.inputStream.available(); bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE); bytesRead = readResult.inputStream.read(buffer, 0, bufferSize); // Send a progress event. progress.setLoaded(totalBytes); PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject()); progressResult.setKeepCallback(true); context.sendPluginResult(progressResult); } // send multipart form data necessary after file data... sendStream.write(tailParamsBytes); totalBytes += tailParamsBytes.length; sendStream.flush(); } finally { safeClose(readResult.inputStream); safeClose(sendStream); } context.currentOutputStream = null; Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength); //------------------ read the SERVER RESPONSE String responseString; int responseCode = conn.getResponseCode(); Log.d(LOG_TAG, "response code: " + responseCode); Log.d(LOG_TAG, "response headers: " + conn.getHeaderFields()); TrackingInputStream inStream = null; try { inStream = getInputStream(conn); synchronized (context) { if (context.aborted) { return; } context.currentInputStream = inStream; } ByteArrayOutputStream out = new ByteArrayOutputStream( Math.max(1024, conn.getContentLength())); byte[] buffer = new byte[1024]; int bytesRead = 0; // write bytes to file while ((bytesRead = inStream.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); } responseString = out.toString("UTF-8"); } finally { context.currentInputStream = null; safeClose(inStream); } Log.d(LOG_TAG, "got response from server"); Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length()))); // send request and retrieve response result.setResponseCode(responseCode); result.setResponse(responseString); context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject())); } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), e); Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes."); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); } catch (Throwable t) { // Shouldn't happen, but will JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn); Log.e(LOG_TAG, error.toString(), t); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } finally { synchronized (activeRequests) { activeRequests.remove(objectId); } if (conn != null) { // Revert back to the proper verifier and socket factories // Revert back to the proper verifier and socket factories if (trustEveryone && useHttps) { HttpsURLConnection https = (HttpsURLConnection) conn; https.setHostnameVerifier(oldHostnameVerifier); https.setSSLSocketFactory(oldSocketFactory); } } } } }); }
From source file:com.adobe.phonegap.contentsync.Sync.java
private boolean download(final String source, final File file, final JSONObject headers, final ProgressEvent progress, final CallbackContext callbackContext, final boolean trustEveryone) { Log.d(LOG_TAG, "download " + source); if (!Patterns.WEB_URL.matcher(source).matches()) { sendErrorMessage("Invalid URL", INVALID_URL_ERROR, callbackContext); return false; }/*from ww w .ja va2 s . c om*/ final CordovaResourceApi resourceApi = webView.getResourceApi(); final Uri sourceUri = resourceApi.remapUri(Uri.parse(source)); int uriType = CordovaResourceApi.getUriType(sourceUri); final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS; final boolean isLocalTransfer = !useHttps && uriType != CordovaResourceApi.URI_TYPE_HTTP; synchronized (progress) { if (progress.isAborted()) { return false; } } HttpURLConnection connection = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; PluginResult result = null; TrackingInputStream inputStream = null; boolean cached = false; OutputStream outputStream = null; try { OpenForReadResult readResult = null; final Uri targetUri = resourceApi.remapUri(Uri.fromFile(file)); progress.setTargetFile(file); progress.setStatus(STATUS_DOWNLOADING); Log.d(LOG_TAG, "Download file: " + sourceUri); Log.d(LOG_TAG, "Target file: " + file); Log.d(LOG_TAG, "size = " + file.length()); if (isLocalTransfer) { readResult = resourceApi.openForRead(sourceUri); if (readResult.length != -1) { progress.setTotal(readResult.length); } inputStream = new SimpleTrackingInputStream(readResult.inputStream); } else { // connect to server // Open a HTTP connection to the URL based on protocol 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); } connection.setRequestMethod("GET"); // TODO: Make OkHttp use this CookieManager by default. String cookie = getCookies(sourceUri.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_NOT_MODIFIED) { cached = true; connection.disconnect(); sendErrorMessage("Resource not modified: " + source, CONNECTION_ERROR, callbackContext); return false; } else { if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) { // Only trust content-length header if we understand // the encoding -- identity or gzip int connectionLength = connection.getContentLength(); if (connectionLength != -1) { if (connectionLength > getFreeSpace()) { cached = true; connection.disconnect(); sendErrorMessage("Not enough free space to download", CONNECTION_ERROR, callbackContext); return false; } else { progress.setTotal(connectionLength); } } } inputStream = getInputStream(connection); } } if (!cached) { try { synchronized (progress) { if (progress.isAborted()) { return false; } //progress.connection = connection; } // write bytes to file byte[] buffer = new byte[MAX_BUFFER_SIZE]; int bytesRead = 0; outputStream = resourceApi.openOutputStream(targetUri); while ((bytesRead = inputStream.read(buffer)) > 0) { synchronized (progress) { if (progress.isAborted()) { return false; } } Log.d(LOG_TAG, "bytes read = " + bytesRead); outputStream.write(buffer, 0, bytesRead); // Send a progress event. progress.setLoaded(inputStream.getTotalRawBytesRead()); updateProgress(callbackContext, progress); } } finally { synchronized (progress) { //progress.connection = null; } safeClose(inputStream); safeClose(outputStream); } } } catch (Throwable e) { sendErrorMessage(e.getLocalizedMessage(), CONNECTION_ERROR, callbackContext); } finally { 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); } } } return true; }
From source file:com.remobile.filetransfer.FileTransfer.java
/** * Uploads the specified file to the server URL provided using an HTTP multipart request. * * @param source Full path of the file on the file system * @param target URL of the server to receive the file * @param args JSON Array of args * @param callbackContext callback id for optional progress reports * <p>//from w ww. ja v a2 s .co m * args[2] fileKey Name of file request parameter * args[3] fileName File name to be used on server * args[4] mimeType Describes file content type * args[5] params key:value pairs of user-defined parameters * @return FileUploadResult containing result of upload request */ private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException { Log.d(LOG_TAG, "upload " + source + " to " + target); // Setup the options final String fileKey = getArgument(args, 2, "file"); 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. 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 = new CordovaResourceApi(getReactApplicationContext()); Log.d(LOG_TAG, "fileKey: " + fileKey); 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; if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) { JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null); Log.e(LOG_TAG, "Unsupported URI: " + targetUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } this.cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection conn = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; int totalBytes = 0; int fixedLength = -1; try { // Create return object FileUploadResult result = new FileUploadResult(); FileProgressResult progress = new FileProgressResult(); //------------------ 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); // Allow Outputs conn.setDoOutput(true); // Don't use a cached copy. conn.setUseCaches(false); // Use a post method. conn.setRequestMethod(httpMethod); // if we specified a Content-Type header, don't do multipart form upload boolean multipartFormUpload = (headers == null) || !headers.has("Content-Type"); if (multipartFormUpload) { conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); } // Handle the other headers if (headers != null) { addHeadersToRequest(conn, headers); } /* * Store the non-file portions of the multipart data as a string, so that we can add it * to the contentSize, since it is part of the body of the HTTP request. */ StringBuilder beforeData = new StringBuilder(); try { for (Iterator<?> iter = params.keys(); iter.hasNext();) { Object key = iter.next(); if (!String.valueOf(key).equals("headers")) { beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END); beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()) .append('"'); beforeData.append(LINE_END).append(LINE_END); beforeData.append(params.getString(key.toString())); beforeData.append(LINE_END); } } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END); beforeData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";"); beforeData.append(" filename=\"").append(fileName).append('"').append(LINE_END); beforeData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END); byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8"); byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END) .getBytes("UTF-8"); // Get a input stream of the file on the phone CordovaResourceApi.OpenForReadResult readResult = resourceApi.openForRead(sourceUri); int stringLength = beforeDataBytes.length + tailParamsBytes.length; if (readResult.length >= 0) { fixedLength = (int) readResult.length; if (multipartFormUpload) fixedLength += stringLength; progress.setLengthComputable(true); progress.setTotal(fixedLength); } Log.d(LOG_TAG, "Content Length: " + fixedLength); // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices. // http://code.google.com/p/android/issues/detail?id=3164 // It also causes OOM if HTTPS is used, even on newer devices. boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps); useChunkedMode = useChunkedMode || (fixedLength == -1); if (useChunkedMode) { conn.setChunkedStreamingMode(MAX_BUFFER_SIZE); // Although setChunkedStreamingMode sets this header, setting it explicitly here works // around an OutOfMemoryException when using https. conn.setRequestProperty("Transfer-Encoding", "chunked"); } else { conn.setFixedLengthStreamingMode(fixedLength); } conn.connect(); OutputStream sendStream = null; try { sendStream = conn.getOutputStream(); synchronized (context) { if (context.aborted) { return; } context.connection = conn; } if (multipartFormUpload) { //We don't want to change encoding, we just want this to write for all Unicode. sendStream.write(beforeDataBytes); totalBytes += beforeDataBytes.length; } // create a buffer of maximum size 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 = readResult.inputStream.read(buffer, 0, bufferSize); long prevBytesRead = 0; while (bytesRead > 0) { result.setBytesSent(totalBytes); sendStream.write(buffer, 0, bytesRead); totalBytes += bytesRead; if (totalBytes > prevBytesRead + 102400) { prevBytesRead = totalBytes; Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes"); } bytesAvailable = readResult.inputStream.available(); bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE); bytesRead = readResult.inputStream.read(buffer, 0, bufferSize); // Send a progress event. progress.setLoaded(totalBytes); FileTransfer.this.sendJSEvent("UploadProgress-" + objectId, JsonConvert.jsonToReact(progress.toJSONObject())); } if (multipartFormUpload) { // send multipart form data necessary after file data... sendStream.write(tailParamsBytes); totalBytes += tailParamsBytes.length; } sendStream.flush(); } finally { safeClose(readResult.inputStream); safeClose(sendStream); } synchronized (context) { context.connection = null; } Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength); //------------------ read the SERVER RESPONSE String responseString; int responseCode = conn.getResponseCode(); Log.d(LOG_TAG, "response code: " + responseCode); Log.d(LOG_TAG, "response headers: " + conn.getHeaderFields()); TrackingInputStream inStream = null; try { inStream = getInputStream(conn); synchronized (context) { if (context.aborted) { return; } context.connection = conn; } ByteArrayOutputStream out = new ByteArrayOutputStream( Math.max(1024, conn.getContentLength())); byte[] buffer = new byte[1024]; int bytesRead = 0; // write bytes to file while ((bytesRead = inStream.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); } responseString = out.toString("UTF-8"); } finally { synchronized (context) { context.connection = null; } safeClose(inStream); } Log.d(LOG_TAG, "got response from server"); Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length()))); // send request and retrieve response result.setResponseCode(responseCode); result.setResponse(responseString); context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject())); } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn, e); Log.e(LOG_TAG, error.toString(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, e); Log.e(LOG_TAG, error.toString(), e); Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes."); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); } catch (Throwable t) { // Shouldn't happen, but will JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, t); Log.e(LOG_TAG, error.toString(), t); context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); } finally { synchronized (activeRequests) { activeRequests.remove(objectId); } if (conn != null) { // Revert back to the proper verifier and socket factories // Revert back to the proper verifier and socket factories if (trustEveryone && useHttps) { HttpsURLConnection https = (HttpsURLConnection) conn; https.setHostnameVerifier(oldHostnameVerifier); https.setSSLSocketFactory(oldSocketFactory); } } } } }); }
From source file:org.apache.cordova.filetransfer.FileTransfer.java
/** * Downloads a file form a given URL and saves it to the specified directory. * * @param source URL of the server to receive the file * @param target Full path of the file on the file system *///ww w . j ava2 s . c om 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 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, null); Log.e(LOG_TAG, "Unsupported URI: " + sourceUri); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } /* This code exists for compatibility between 3.x and 4.x versions of Cordova. * Previously the CordovaWebView class had a method, getWhitelist, which would * return a Whitelist object. Since the fixed whitelist is removed in Cordova 4.x, * the correct call now is to shouldAllowRequest from the plugin manager. */ Boolean shouldAllowRequest = null; if (isLocalTransfer) { shouldAllowRequest = true; } if (shouldAllowRequest == null) { try { Method gwl = webView.getClass().getMethod("getWhitelist"); Whitelist whitelist = (Whitelist) gwl.invoke(webView); shouldAllowRequest = whitelist.isUrlWhiteListed(source); } catch (NoSuchMethodException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } if (shouldAllowRequest == null) { try { Method gpm = webView.getClass().getMethod("getPluginManager"); PluginManager pm = (PluginManager) gpm.invoke(webView); Method san = pm.getClass().getMethod("shouldAllowRequest", String.class); shouldAllowRequest = (Boolean) san.invoke(pm, source); } catch (NoSuchMethodException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } if (!Boolean.TRUE.equals(shouldAllowRequest)) { Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'"); JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401, null); callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error)); return; } final RequestContext context = new RequestContext(source, target, callbackContext); synchronized (activeRequests) { activeRequests.put(objectId, context); } cordova.getThreadPool().execute(new Runnable() { public void run() { if (context.aborted) { return; } HttpURLConnection connection = null; HostnameVerifier oldHostnameVerifier = null; SSLSocketFactory oldSocketFactory = null; File file = null; PluginResult result = null; TrackingInputStream inputStream = null; boolean cached = false; OutputStream outputStream = null; try { OpenForReadResult readResult = null; file = resourceApi.mapUriToFile(targetUri); context.targetFile = file; Log.d(LOG_TAG, "Download file:" + sourceUri); FileProgressResult progress = new FileProgressResult(); if (isLocalTransfer) { readResult = resourceApi.openForRead(sourceUri); if (readResult.length != -1) { progress.setLengthComputable(true); progress.setTotal(readResult.length); } inputStream = new SimpleTrackingInputStream(readResult.inputStream); } else { // connect to server // Open a HTTP connection to the URL based on protocol 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); } connection.setRequestMethod("GET"); // TODO: Make OkHttp use this CookieManager by default. String cookie = getCookies(sourceUri.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_NOT_MODIFIED) { cached = true; connection.disconnect(); Log.d(LOG_TAG, "Resource not modified: " + source); JSONObject error = createFileTransferError(NOT_MODIFIED_ERR, source, target, connection, null); result = new PluginResult(PluginResult.Status.ERROR, error); } else { if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) { // Only trust content-length header if we understand // the encoding -- identity or gzip if (connection.getContentLength() != -1) { progress.setLengthComputable(true); progress.setTotal(connection.getContentLength()); } } inputStream = getInputStream(connection); } } if (!cached) { try { synchronized (context) { if (context.aborted) { return; } context.connection = connection; } // write bytes to file byte[] buffer = new byte[MAX_BUFFER_SIZE]; int bytesRead = 0; outputStream = resourceApi.openOutputStream(targetUri); while ((bytesRead = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, bytesRead); // Send a progress event. progress.setLoaded(inputStream.getTotalRawBytesRead()); PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject()); progressResult.setKeepCallback(true); context.sendPluginResult(progressResult); } } finally { synchronized (context) { context.connection = null; } safeClose(inputStream); safeClose(outputStream); } Log.d(LOG_TAG, "Saved file: " + target); // create FileEntry object Class webViewClass = webView.getClass(); PluginManager pm = null; try { Method gpm = webViewClass.getMethod("getPluginManager"); pm = (PluginManager) gpm.invoke(webView); } catch (NoSuchMethodException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } if (pm == null) { try { Field pmf = webViewClass.getField("pluginManager"); pm = (PluginManager) pmf.get(webView); } catch (NoSuchFieldException e) { } catch (IllegalAccessException e) { } } file = resourceApi.mapUriToFile(targetUri); context.targetFile = file; FileUtils filePlugin = (FileUtils) pm.getPlugin("File"); if (filePlugin != null) { JSONObject fileEntry = filePlugin.getEntryForFile(file); if (fileEntry != null) { result = new PluginResult(PluginResult.Status.OK, fileEntry); } else { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, null); Log.e(LOG_TAG, "File plugin cannot represent download path"); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } } else { Log.e(LOG_TAG, "File plugin not found; cannot save downloaded file"); result = new PluginResult(PluginResult.Status.ERROR, "File plugin not found; cannot save downloaded file"); } } } catch (FileNotFoundException e) { JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (IOException e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); result = new PluginResult(PluginResult.Status.JSON_EXCEPTION); } catch (Throwable e) { JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e); Log.e(LOG_TAG, error.toString(), e); result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error); } finally { synchronized (activeRequests) { 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)); } // Remove incomplete download. if (!cached && result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) { file.delete(); } context.sendPluginResult(result); } } }); }