All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-main.org.awakefw.file.http.HttpTransferOne Maven / Gradle / Ivy

Go to download

Awake FILE is a secure Open Source framework that allows to program very easily file uploads/downloads and RPC through http. File transfers include powerful features like file chunking and automatic recovery mechanism. Security has been taken into account from the design: server side allows to specify strong security rules in order to protect the files and to secure the RPC calls.

There is a newer version: 3.0
Show newest version
/*
 * This file is part of Awake FILE. 
 * Awake FILE: Easy file upload & download over HTTP with Java.                                    
 * Copyright (C) 2014,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * Awake FILE is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * Awake FILE is distributed in the hope that it will be useful,               
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             
 * Lesser General Public License for more details.                               
 *                                                                               
 * You should have received a copy of the GNU Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.awakefw.file.http;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.sql.BatchUpdateException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.ChallengeState;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.awakefw.commons.api.client.AwakeProgressManager;
import org.awakefw.commons.api.client.HttpProtocolParameters;
import org.awakefw.commons.api.client.HttpProxy;
import org.awakefw.commons.api.client.RemoteException;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.api.util.DefaultParms;
import org.awakefw.file.http.exception.HttpTransferInterruptedException;
import org.awakefw.file.util.AwakeClientLogger;
import org.awakefw.file.util.AwakeFileUtil;
import org.awakefw.file.util.AwakeSystemUtil;
import org.awakefw.file.util.Tag;
import org.awakefw.file.util.TransferStatus;

/**
 * HttpTransferOne - Please note that in implementation, result is read in the
 * send method to be sure to release ASAP the server. 
* */ public class HttpTransferOne implements HttpTransfer { /** The debug flag */ private static boolean DEBUG = AwakeDebug.isSet(HttpTransferOne.class); /** Universal and clean line separator */ public static String CR_LF = System.getProperty("line.separator"); public final static String HTTP_WWW_GOOGLE_COM = "http://www.google.com"; /** Response from http server container */ private String m_responseBody = null; /** The http client in use */ private DefaultHttpClient httpClient; /** Target host. Will be passed to httpClient.execute */ private HttpHost targetHost = null; /** The servlet path. Example "/AwakeSqlManager */ private String servletPath = null; /** Http context. Will be passed to httpClient.execute */ private BasicHttpContext localHttpContext; // // Server Parameter // /** The url to the main controler servlet session */ private String url = null; /** The Http Proxy instance */ private HttpProxy httpProxy = null; /** The Http Parameters instance */ private HttpProtocolParameters httpProtocolParameters = null; /** The awake class tht follows the file transfer */ private AwakeProgressManager awakeProgressManager = null; /** If true, all results will be received in a temp file */ private boolean doReceiveInFile = false; /** The file that contains the result of a http request send() */ private File receiveFile = null; /** The Http Status code of the last send() */ private int statusCode = 0; /** Says client side is always repeatable. */ private boolean repeatable = false; /** * Default constructor.  *

* * @param url * the URL path to the Sql Manager Servlet * @param httpProxy * the proxy (may be null for default settings) * @param httpProtocolParameters * the http protocol supplementary parameters (may be null for * default settings) * @param awakeProgressManager * the Awake Progress Manager may be null for default settings */ public HttpTransferOne(String url, HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters, AwakeProgressManager awakeProgressManager) { if (url == null) { throw new IllegalArgumentException("url can not be null!"); } this.url = url; this.httpProxy = httpProxy; this.httpProtocolParameters = httpProtocolParameters; this.awakeProgressManager = awakeProgressManager; httpClient = new DefaultHttpClient(); servletPath = HttpTransferOneUtil.getServletPathFromUrl(url); String httpHost = url; httpHost = StringUtils.substringBefore(url, servletPath); //debug("url : " + url); //debug("servletPath: " + servletPath); //debug("httpHost : " + httpHost); HttpHostPartsExtractor httpHostPartsExtractor = new HttpHostPartsExtractor(httpHost); targetHost = new HttpHost(httpHostPartsExtractor.getHostName(), httpHostPartsExtractor.getPort(), httpHostPartsExtractor.getSchemeName()); //debug("hostname: " + targetHost.getHostName()); //debug("port : " + targetHost.getPort()); //debug("scheme : " + targetHost.getSchemeName()); // Will fix later the necessary IOException wrapping try { setProxyAndProtocolParameters(httpClient); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * Constructor to use only for for URL download. *

* * @param httpProxy * the proxy (may be null for default settings) * @param httpProtocolParameters * the http protocol supplementary parameters * @param awakeProgressManager * the Awake Progress Manager (may be null for default settings) */ public HttpTransferOne(HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters, AwakeProgressManager awakeProgressManager) { this.httpProxy = httpProxy; this.httpProtocolParameters = httpProtocolParameters; this.awakeProgressManager = awakeProgressManager; } /** * Allows to set an Awake Progress Manager instance. * * @param awakeProgressManager * the Awake Progress Manager instance */ @Override public void setAwakeProgressManager( AwakeProgressManager awakeProgressManager) { this.awakeProgressManager = awakeProgressManager; } /** * Set the proxy values for this session * * @param httpClient * the Http Client instance */ private void setProxyAndProtocolParameters(DefaultHttpClient httpClient) throws IOException { // Say if we want to allow all certificates (including "bad" and // self-signed) if (httpProtocolParameters != null && httpProtocolParameters.isAcceptAllSslCertificates() && (url == null || url.toLowerCase().startsWith("https://")) && !AwakeSystemUtil.isAndroid()) { HttpTransferOneUtil.acceptSelfSignedSslCert(httpClient); } if (httpProtocolParameters != null) { repeatable = httpProtocolParameters.isRepeatable(); Set httpParamaterNames = httpProtocolParameters .getHttpClientParameterNames(); for (String parameter : httpParamaterNames) { Object value = httpProtocolParameters .getHttpClientParameter(parameter); try { httpClient.getParams().setParameter(parameter, value); } catch (Exception e) { String className = "unknown"; try { className = value.getClass().getName(); } catch (Exception e1) { AwakeClientLogger.log(Level.WARNING, e1.toString()); } throw new IllegalArgumentException( Tag.AWAKE_USER_CONFIG_FAIL + "Impossible to call httpClient.getParams().setParameter(parameter, value) for parameter: " + parameter + " and value: " + value + " were value is of Java class: " + className); } } } // httpClient.getParams().setParameter("http.socket.timeout", new // Integer(0)); // Reset proxy if null and return if (httpProxy == null) { try { displayErrroMessageIfNoProxySet(); } catch (Exception e) { e.printStackTrace(); } // reset System.setProperty("http.proxyHost", ""); System.setProperty("http.proxyPort", ""); return; } String httpProxyAddress = httpProxy.getAddress(); int httpProxyPort = httpProxy.getPort(); String httpProxyUsername = httpProxy.getUsername(); String httpProxyPassword = httpProxy.getPassword(); if (DEBUG) { // System.out.println("httpProxyAddress : " + httpProxyAddress); // System.out.println("httpProxyPort : " + httpProxyPort); // System.out.println("httpProxyUsername: " + httpProxyUsername); // System.out.println("httpProxyPassword: " + httpProxyPassword); } if (httpProxyAddress != null && httpProxyAddress.length() > 0) { /* System.setProperty("http.proxyHost", httpProxyAddress); System.setProperty("http.proxyPort", Integer.toString(httpProxyPort)); System.setProperty("https.proxyHost", httpProxyAddress); System.setProperty("https.proxyPort", Integer.toString(httpProxyPort)); */ HttpHost proxy = new HttpHost(httpProxyAddress, httpProxyPort); httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); if (httpProxyUsername == null || httpProxyUsername.isEmpty()) { localHttpContext = new BasicHttpContext(); } else { // targetHost may be null if we use AwakeUrl API if (targetHost != null) { // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local auth // cache BasicScheme basicAuthScheme = new BasicScheme( ChallengeState.PROXY); if (httpProxy.getWorkstation() == null) { basicAuthScheme = new BasicScheme(ChallengeState.PROXY); } else { basicAuthScheme = new BasicScheme(ChallengeState.TARGET); } authCache.put(targetHost, basicAuthScheme); localHttpContext = new BasicHttpContext(); localHttpContext.setAttribute(ClientContext.AUTH_CACHE, authCache); } if (httpProxy.getWorkstation() != null) { // httpClient.getAuthSchemes().register("ntlm", new // NTLMSchemeFactory()); String workstation = httpProxy.getWorkstation(); String domain = httpProxy.getDomain(); httpClient.getCredentialsProvider().setCredentials( new AuthScope(httpProxyAddress, httpProxyPort), new NTCredentials(httpProxyUsername, httpProxyPassword, workstation, domain)); } else { httpClient.getCredentialsProvider().setCredentials( new AuthScope(httpProxyAddress, httpProxyPort), new UsernamePasswordCredentials(httpProxyUsername, httpProxyPassword)); } } } } /** * @return the http status code */ public int getHttpStatusCode() { return this.statusCode; } /** * Send a String to the HTTP server. * * @param requestParams * the request parameters list with (parameter, value) * * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * @throws ConnectException * The Host is correct but the Servlet * (http://www.acme.org/Servlet) failed with a status <> OK * (200). (if the host is incorrect, or is impossible to connect * to- Tomcat down - will throw a sub exception * HttpHostConnectException) * @throws RemoteException * an exception has been thrown on the server side * @throws SecurityException * the url is not secured with https (SSL) * @throws IOException * For all other IO / Network / System Error */ public void send(List requestParams) throws UnknownHostException, ConnectException, RemoteException, IOException { this.send(requestParams, null); } /** * Send a String to the HTTP server and upload an InputStream * * @param requestParams * the request parameters list with (parameter, value) * @param in * the InputStream to upload * * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * @throws ConnectException * The Host is correct but the Servlet * (http://www.acme.org/Servlet) failed with a status <> OK * (200). (if the host is incorrect, or is impossible to connect * to- Tomcat down - will throw a sub exception * HttpHostConnectException) * @throws RemoteException * an exception has been thrown on the server side * @throws SecurityException * the url is not secured with https (SSL) * @throws IOException * For all other IO / Network / System Error */ public void send(List requestParams, InputStream in) throws UnknownHostException, ConnectException, RemoteException, IOException { statusCode = 0; // Reset it! m_responseBody = null; // Reset it! DefaultHttpClient localHttpClient = null; BufferedReader bufferedReader = null; File entityContentFile = null; HttpEntity entity = null; File tempfileForUpload = null; try { // We need to Html convert & maybe encrypt the parameters BasicNameValuePairConvertor basicNameValuePairConvertor = new BasicNameValuePairConvertor( requestParams, httpProtocolParameters); requestParams = basicNameValuePairConvertor.convert(); //debug("requestParams : " + requestParams); //debug("requestParams.length: " + requestParams.toString().length()); HttpPost httpPost = new HttpPost(servletPath); HttpResponse response = null; statusCode = 0; if (in == null) { httpPost.setEntity(new UrlEncodedFormEntity(requestParams, "UTF-8")); } else { MultipartEntity multipartEntity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE); for (BasicNameValuePair basicNameValuePair : requestParams) { String paramName = basicNameValuePair.getName(); String paramValue = basicNameValuePair.getValue(); // For usual String parameters multipartEntity.addPart(paramName, new StringBody(paramValue.toString(), "text/plain", Charset.forName("UTF-8"))); } // If we use a proxy, we must use a repeatable Entity // Some proxies retry the file uplaod (Neotunnel) boolean proxyInUse = httpProxy == null ? false:true; if (proxyInUse || repeatable) { tempfileForUpload = createFileToUpload(in); debug("sending chunck with FileBodyForEngine"); // For File parameters multipartEntity.addPart("file", new FileBodyForEngine(tempfileForUpload, "application/zip", httpProtocolParameters, awakeProgressManager)); } else { debug("sending chunck with InputStreamBodyForEngine"); // For File parameters multipartEntity.addPart("file", new InputStreamBodyForEngine(in, "application/zip", httpProtocolParameters, awakeProgressManager)); } httpPost.setEntity(multipartEntity); } // Execute the request response = httpClient.execute(targetHost, httpPost, localHttpContext); // Analyse the error after request execution // Interrupted by user if (awakeProgressManager != null && awakeProgressManager.isCancelled()) { return; } statusCode = response.getStatusLine().getStatusCode(); // Get hold of the response entity entity = response.getEntity(); if (statusCode != HttpStatus.SC_OK) { // The server is up, but the servlet is not accessible //throw new ConnectException(url + ": Servlet failed: " // + response.getStatusLine() + " status: " + statusCode); } // Get immediately the content as input stream // do *NOT* use a buffered stream ==> Will fail with SSL handshakes! entityContentFile = createAwakeTempFile(); saveEntityContentToFile(entityContentFile, entity); // Read content of first line. bufferedReader = new BufferedReader(new InputStreamReader( new FileInputStream(entityContentFile))); // line 1: Contains the request status - line 2: Contains the datas String awakeStatus = bufferedReader.readLine(); //debug("awakeStatus : " + awakeStatus); if (doReceiveInFile) { // Content is saved back into a file, minus the first line // status receiveFile = createAwakeTempFile(); copyResponseIntoFile(bufferedReader, receiveFile); } else { int maxLengthForString = DefaultParms.DEFAULT_MAX_LENGTH_FOR_STRING; if (httpProtocolParameters != null) { maxLengthForString = httpProtocolParameters .getMaxLengthForString(); } if (entityContentFile.length() > maxLengthForString) { throw new IOException("Response too big for String: > " + maxLengthForString + " bytes."); } copyResponseIntoString(bufferedReader); } // Analyse applicative response header // "SEND_OK" // "SEND_FAILED" if (awakeStatus.startsWith(TransferStatus.SEND_OK)) { return; // OK! } else if (awakeStatus.startsWith(TransferStatus.SEND_FAILED)) { BufferedReader bufferedReaderException = null; try { // We must throw the remote exception if (doReceiveInFile) { bufferedReaderException = new BufferedReader( new FileReader(receiveFile)); throwTheRemoteException(bufferedReaderException); } else { bufferedReaderException = new BufferedReader( new StringReader(m_responseBody)); throwTheRemoteException(bufferedReaderException); } } finally { IOUtils.closeQuietly(bufferedReaderException); if (doReceiveInFile && !DEBUG) { receiveFile.delete(); } } } else { throw new IOException( Tag.AWAKE_USER_CONFIG_FAIL + "The URL does dot correspond to an Awake Servlet: " + url); } } finally { if (localHttpClient != null) { localHttpClient.getConnectionManager().shutdown(); } // Reset doReceiveInFile doReceiveInFile = false; if (entity != null) { consume(entity); } IOUtils.closeQuietly(bufferedReader); // 12/11/10 19:15 NDP - HttpTransferOne.send(): test null file // before entityContentFile.delete() if (entityContentFile != null) { //debug("entityContentFile: " + entityContentFile); entityContentFile.delete(); } if (tempfileForUpload != null) { tempfileForUpload.delete(); } } } /** * Wrapper for EntityUtils.consume(entity) that does not exist on Android * @param entity * @throws IOException */ private void consume(HttpEntity entity) throws IOException{ if (!AwakeSystemUtil.isAndroid()) { EntityUtils.consume(entity); } } /** * Creates a file to uplaod from the input stream THAT MUST NOT BE CLOSED * because it may be reused in subsequent call * * @param in * the input stream on the file to upload * @return a temp file created to upload * @throws FileNotFoundException * @throws IOException */ private File createFileToUpload(InputStream in) throws FileNotFoundException, IOException { long chunkLength = DefaultParms.DEFAULT_UPLOAD_CHUNK_LENGTH; int uploadBufferSize = DefaultParms.DEFAULT_UPLOAD_BUFFER_SIZE; // For Chunk Length comparison. If buffer read > chunk length ==> exit long total = 0; byte[] tmp = new byte[uploadBufferSize]; int len; File file = createAwakeTempFile(); //debug("createFileToUpload file: " + file); OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(file)); while ((len = in.read(tmp)) >= 0) { total += len; out.write(tmp, 0, len); // Exit if chunk length is reached. We just send the chunck, // InputStream // will be reused if (chunkLength > 0 && total > chunkLength) { break; } } } finally { IOUtils.closeQuietly(out); } return file; } /** * * Throws an Exception * * @param bufferedReader * the reader that contains the remote thrown exception * * @throws IOException * @throws RemoteException * @throws SecurityException */ public static void throwTheRemoteException(BufferedReader bufferedReader) throws RemoteException, IOException { String exceptionName = bufferedReader.readLine(); if (exceptionName.equals("null")) { exceptionName = null; } if (exceptionName == null) { throw new IOException( Tag.AWAKE_PRODUCT_FAIL + "Remote Exception type/name not found in servlet output stream"); } String message = bufferedReader.readLine(); if (message.equals("null")) { message = null; } StringBuffer sb = new StringBuffer(); String line = null; while ((line = bufferedReader.readLine()) != null) { // All subsequent lines contain the result sb.append(line); sb.append(CR_LF); } String remoteStackTrace = null; if (sb.length() > 0) { remoteStackTrace = sb.toString(); } // Ok, build the authorized Exception if (exceptionName.contains(Tag.ClassNotFoundException)) { throw new RemoteException(message, new ClassNotFoundException( message), remoteStackTrace); } else if (exceptionName.contains(Tag.InstantiationException)) { throw new RemoteException(message, new InstantiationException( message), remoteStackTrace); } else if (exceptionName.contains(Tag.NoSuchMethodException)) { throw new RemoteException(message, new NoSuchMethodException( message), remoteStackTrace); } else if (exceptionName.contains(Tag.InvocationTargetException)) { throw new RemoteException(message, new InvocationTargetException( new Exception(message)), remoteStackTrace); } // // SQL Exceptions // else if (exceptionName.contains(Tag.SQLException)) { throw new RemoteException(message, new SQLException(message), remoteStackTrace); } else if (exceptionName.contains(Tag.BatchUpdateException)) { throw new RemoteException(message, new BatchUpdateException(), remoteStackTrace); } // // Awake Security Failure // else if (exceptionName.contains(Tag.SecurityException)) { // throw new RemoteException(message, new // SecurityException(message), remoteStackTrace); throw new SecurityException(message); } // // IOExceptions // else if (exceptionName.contains(Tag.FileNotFoundException)) { throw new RemoteException(message, new FileNotFoundException( message), remoteStackTrace); } else if (exceptionName.contains(Tag.IOException)) { throw new RemoteException(message, new IOException(message), remoteStackTrace); } // // Awake Failure: these errors should never be thrown by Awake FILE and // Awake SQL server : // - NullPointerException // - IllegalArgumentException // else if (exceptionName.contains(Tag.NullPointerException)) { throw new RemoteException(message, new NullPointerException(message), remoteStackTrace); } else if (exceptionName.contains(Tag.IllegalArgumentException)) { throw new RemoteException(message, new IllegalArgumentException( message), remoteStackTrace); } else { // All other cases ==> IOException with no cause throw new RemoteException("Remote " + exceptionName + ": " + message, new IOException(message), remoteStackTrace); } } /** * Immediately Save the entity content into file and release it * * @param entityContentFile * the file where to save the entigy content * @param entity * the http entity * @throws IOException * @throws IllegalStateException * @throws FileNotFoundException */ private void saveEntityContentToFile(File entityContentFile, HttpEntity entity) throws IOException, IllegalStateException, FileNotFoundException { InputStream in; in = entity.getContent(); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(entityContentFile)); try { IOUtils.copy(in, out); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); } } /** * Copy the response into a string * * @param bufferedReader * the buffered content of the centiy, minus the first line * @throws IOException */ private void copyResponseIntoString(BufferedReader bufferedReader) throws IOException { StringBuffer sb = new StringBuffer(); String line = null; while ((line = bufferedReader.readLine()) != null) { // All subsequent lines contain the result sb.append(line); sb.append(CR_LF); } m_responseBody = sb.toString(); //debug("m_responseBody: " + m_responseBody + ":"); } /** * Transform the response stream into a file * * @param bufferedReader * the input response stream as line reader * @param file * the output file to create * * @throws IOException * if any IOException occurs during the process */ private void copyResponseIntoFile(BufferedReader bufferedReader, File file) throws IOException { BufferedOutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(file)); String line = null; while ((line = bufferedReader.readLine()) != null) { // All subsequent lines contain the result out.write((line + CR_LF).getBytes()); } out.flush(); } finally { IOUtils.closeQuietly(out); } } /** * Send a String to the HTTP server using receive httpServerProgram Servlet * and download a file * * @param requestParams * the request parameters list with (parameter, value) * @param fileLength * the file length (for the progress indicator). If 0, will not * be used * @param file * the file to create on the client side (PC) * * @throws IllegalArgumentException * if the file to download is null * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * @throws ConnectException * The Host is correct but the Servlet * (http://www.acme.org/Servlet) failed with a status <> OK * (200). * @throws IOException * For all other IO / Network / System Error */ @SuppressWarnings("resource") public void download(List requestParams, File file) throws IllegalArgumentException, UnknownHostException, ConnectException, RemoteException, IOException { if (file == null) { throw new IllegalArgumentException( "file to create can not be null!"); } statusCode = 0; // Reset it! m_responseBody = null; // Reset it! //DefaultHttpClient httpClient = null; HttpPost httpPost = null; InputStream in = null; OutputStream out = null; HttpEntity entity = null; try { // We need to Html convert & maybe encrypt the parameters BasicNameValuePairConvertor basicNameValuePairConvertor = new BasicNameValuePairConvertor( requestParams, httpProtocolParameters); requestParams = basicNameValuePairConvertor.convert(); // Create an instance of HttpClient. //httpClient = new DefaultHttpClient(); // Set the Proxy & Socket Values //setProxyAndProtocolParameters(httpClient); httpPost = new HttpPost(servletPath); httpPost.setEntity(new UrlEncodedFormEntity(requestParams, "UTF-8")); HttpResponse response = null; // Execute the request and analyse the error response = httpClient.execute(targetHost, httpPost, localHttpContext); statusCode = response.getStatusLine().getStatusCode(); // Get hold of the response entity entity = response.getEntity(); if (statusCode != HttpStatus.SC_OK) { // The server is up, but the servlet is not accessible throw new ConnectException(url + ": Servlet failed: " + response.getStatusLine() + " status: " + statusCode); } //debug("before in = entity.getContent()"); // Read the response body. // Do *NOT* use a buffered input stream ==> Will fail with SSL // handshakes! // in = new BufferedInputStream(entity.getContent()) ; in = entity.getContent(); // debug("" + EntityUtils.toByteArray(entity).length); // debug("getContentLength: " + entity.getContentLength()); // debug("streaming : " + entity.isStreaming()); // debug("isChunked : " + entity.isChunked()); // debug("isRepeatable : " + entity.isRepeatable()); out = new BufferedOutputStream(new FileOutputStream(file)); int downloadBufferSize = DefaultParms.DEFAULT_DOWNLOAD_BUFFER_SIZE; if (httpProtocolParameters != null) { downloadBufferSize = httpProtocolParameters .getDownloadBufferSize(); } byte[] buf = new byte[downloadBufferSize]; int len; int tempLen = 0; // setOwnerNote(message); long filesLength = 0; if (awakeProgressManager != null) { filesLength = awakeProgressManager.getLengthToTransfer(); } // debug("before while ((len = in.read(buf)) > 0) { - filesLength: " // + filesLength); // debug(""); // long totallen = 0; while ((len = in.read(buf)) > 0) { tempLen += len; if (filesLength > 0 && tempLen > filesLength / MAXIMUM_PROGRESS_100) { tempLen = 0; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } addOneToAwakeProgressManager(); // For ProgressMonitor // progress bar } // if (isAwakeProgressManagerInterrupted()) { // throw new InterruptedException(); // } if (isAwakeProgressManagerInterrupted()) { throw new HttpTransferInterruptedException(Tag.AWAKE + "File download interrupted by user."); } //totallen += len; //debug("out.write(buf, 0, len); - totallen: " + totallen); out.write(buf, 0, len); } //debug("before IOUtils.closeQuietly(out);"); // Close now, we will reuse file in setStatusAfterDownload IOUtils.closeQuietly(out); // Sets the status after the file download analyseStatusAfterDownload(file); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(out); if (entity != null) { consume(entity); } } } /** * Send a String to the HTTP server using servlet defined by url and return * the corresponding input stream * * * @param requestParams * the request parameters list with (parameter, value) * @param fileLength * the file length (for the progress indicator). If 0, will not * be used * @param file * the file to create on the client side (PC) * * @throws IllegalArgumentException * if the file to download is null * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * @throws ConnectException * The Host is correct but the Servlet * (http://www.acme.org/Servlet) failed with a status <> OK * (200). * @throws IOException * For all other IO / Network / System Error */ public InputStream getInputStreeam(List requestParams) throws IllegalArgumentException, UnknownHostException, ConnectException, RemoteException, IOException { statusCode = 0; // Reset it! //httpClient = null; HttpPost httpPost = null; InputStream in = null; // Create an instance of HttpClient. //httpClient = new DefaultHttpClient(); // Set the Proxy & Socket Values //setProxyAndProtocolParameters(httpClient); httpPost = new HttpPost(servletPath); httpPost.setEntity(new UrlEncodedFormEntity(requestParams, "UTF-8")); HttpResponse response = null; HttpEntity entity = null; // Execute the request and analyse the error response = httpClient.execute(targetHost, httpPost, localHttpContext); statusCode = response.getStatusLine().getStatusCode(); // Get hold of the response entity entity = response.getEntity(); if (statusCode != HttpStatus.SC_OK) { // The server is up, but the servlet is not accessible throw new ConnectException(url + ": Servlet failed: " + response.getStatusLine() + " status: " + statusCode); } // Read the response body. // Do *NOT* use a buffered input stream ==> Will fail with SSL // handshakes! // in = new BufferedInputStream(entity.getContent()) ; in = entity.getContent(); if (entity != null) { consume(entity); } return in; } /** * Closes the http client used for getInputStream */ @Override public void close() { if (httpClient != null) { httpClient.getConnectionManager().shutdown(); } } /** * Sets the status after the file download * * @param file * the downloaded file */ private void analyseStatusAfterDownload(File file) throws RemoteException, IOException { LineNumberReader lineNumberReader = null; InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); byte[] statusAsBytes = new byte[TransferStatus.SEND_OK.length()]; int readBytes = in.read(statusAsBytes); String readStr = new String(statusAsBytes); //debug("readStr : " + readStr); //debug("readBytes: " + readBytes); // Nothing to read (should not happen, except for empty files...) if (readBytes < TransferStatus.SEND_OK.length()) { return; } // SEND_OK may happen if: 1) Invalid Login 2) FileNotFound if ((readStr != null) && readStr.startsWith(TransferStatus.SEND_OK)) { IOUtils.closeQuietly(in); BufferedReader bufferedReader = new BufferedReader( new FileReader(file)); try { bufferedReader.readLine(); // Read The status line m_responseBody = bufferedReader.readLine(); //debug("m_responseBody: " + m_responseBody); } finally { IOUtils.closeQuietly(bufferedReader); if (!DEBUG) { file.delete(); } } } // SEND_FAILED contains thrown Exceptions: else if ((readStr != null) && readStr.startsWith(TransferStatus.SEND_FAILED)) { IOUtils.closeQuietly(in); BufferedReader bufferedReaderException = new BufferedReader( new FileReader(file)); try { throwTheRemoteException(bufferedReaderException); } finally { IOUtils.closeQuietly(bufferedReaderException); if (!DEBUG) { file.delete(); } } } } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(lineNumberReader); } } /** * Create our own Awake temp file * * @return the tempfile to create with ".awake" prefix in the java.io.tmpdir * directory */ private synchronized File createAwakeTempFile() { String unique = AwakeFileUtil.getUniqueId(); String tempDir = AwakeFileUtil.getAwakeTempDir(); String tempFile = tempDir + File.separator + "http-transfer-one-" + unique + ".awake.txt"; return new File(tempFile); } /** * Create a File from a remote URL. * * @param url * the url of the site. Example http://www.yahoo.com * @param file * the file to create from the download. * * @throws IllegalArgumentException * if the url or the file is null * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * @throws FileNotFoundException * Impossible to connect to the Host. May appear if, for * example, the Web server is down. (Tomcat down ,etc.) * @throws IOException * For all other IO / Network / System Error * @throws InterruptedException * if download is interrupted by user through an * AwakeProgressManager */ @SuppressWarnings("resource") public void downloadUrl(URL url, File file) throws IllegalArgumentException, UnknownHostException, FileNotFoundException, IOException { if (file == null) { throw new IllegalArgumentException("file can not be null!"); } if (url == null) { throw new IllegalArgumentException("url can not be null!"); } statusCode = 0; // Reset it! DefaultHttpClient httpClient = null; HttpGet httpget = null; InputStream in = null; OutputStream out = null; LineNumberReader lineNumberReader = null; try { // Create an instance of HttpClient. httpClient = new DefaultHttpClient(); // Set the Proxy & Socket Values setProxyAndProtocolParameters(httpClient); httpget = new HttpGet(url.toString()); HttpResponse response = null; HttpEntity entity = null; // Execute the request and analyse the error response = httpClient.execute(httpget); statusCode = response.getStatusLine().getStatusCode(); // Get hold of the response entity entity = response.getEntity(); if (statusCode != HttpStatus.SC_OK) { throw new FileNotFoundException("URL not found: " + url + " status line: " + response.getStatusLine() + " status: " + statusCode); } // Read the response body. in = entity.getContent(); //awakeProgressManager.setLengthToTransfer(entity.getContentLength()); out = new BufferedOutputStream(new FileOutputStream(file)); byte[] buf = new byte[4096]; int len; int tempLen = 0; long filesLength = 0; if (awakeProgressManager != null) { filesLength = awakeProgressManager.getLengthToTransfer(); } while ((len = in.read(buf)) > 0) { tempLen += len; if (filesLength > 0 && tempLen > filesLength / MAXIMUM_PROGRESS_100) { tempLen = 0; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } addOneToAwakeProgressManager(); // For ProgressMonitor // progress bar } // if (isAwakeProgressManagerInterrupted()) { // throw new InterruptedException(); // } if (isAwakeProgressManagerInterrupted()) { throw new HttpTransferInterruptedException(Tag.AWAKE + "File download interrupted by user."); } out.write(buf, 0, len); } // We suppose the download is ok: // m_isSendOk = true; } finally { IOUtils.closeQuietly(out); IOUtils.closeQuietly(in); IOUtils.closeQuietly(lineNumberReader); if (httpClient != null) { httpClient.getConnectionManager().shutdown(); } } } /** * Create a File from a remote URL. * * @param url * the url of the site. Example http://www.yahoo.com * @param file * the file to create from the download. * * @throws IllegalArgumentException * if the url or the file is null * @throws UnknownHostException * Host url (http://www.acme.org) does not exists or no Internet * Connection. * * @throws IOException * For all other IO / Network / System Error */ @Override public String getUrlContent(URL url) throws IllegalArgumentException, UnknownHostException, IOException { if (url == null) { throw new IllegalArgumentException("url can not be null!"); } statusCode = 0; // Reset it! DefaultHttpClient httpClient = null; HttpGet httpget = null; InputStream in = null; try { // Create an instance of HttpClient. httpClient = new DefaultHttpClient(); // Set the Proxy & Socket Values setProxyAndProtocolParameters(httpClient); httpget = new HttpGet(url.toString()); HttpResponse response = null; HttpEntity entity = null; // Execute the request and analyze the error response = httpClient.execute(httpget); statusCode = response.getStatusLine().getStatusCode(); // Get hold of the response entity entity = response.getEntity(); if (statusCode != HttpStatus.SC_OK) { throw new FileNotFoundException("URL not found: " + url + " status line: " + response.getStatusLine() + " status: " + statusCode); } // Read the response body. in = entity.getContent(); int downloadBufferSize = DefaultParms.DEFAULT_DOWNLOAD_BUFFER_SIZE; int maxLengthForString = DefaultParms.DEFAULT_MAX_LENGTH_FOR_STRING; if (httpProtocolParameters != null) { downloadBufferSize = httpProtocolParameters .getDownloadBufferSize(); maxLengthForString = httpProtocolParameters .getMaxLengthForString(); } ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[downloadBufferSize]; int len = 0; int totalLen = 0; while ((len = in.read(buf)) > 0) { totalLen += len; if (totalLen > maxLengthForString) { throw new IOException( "URL content is too big for download into a String. " + "Maximum length authorized is: " + maxLengthForString); } out.write(buf, 0, len); } String content = new String(out.toByteArray()); return content; } finally { IOUtils.closeQuietly(in); if (httpClient != null) { httpClient.getConnectionManager().shutdown(); } } } /** * @return true is there is an owner AND it's interrupted */ private boolean isAwakeProgressManagerInterrupted() { if (awakeProgressManager == null) { return false; } return awakeProgressManager.isCancelled(); } /** * Set the owner current value for progression bar * * @param current */ private void addOneToAwakeProgressManager() { if (awakeProgressManager != null) { int current = awakeProgressManager.getProgress(); current++; // awakeProgressManager.setProgress(current); if (current < HttpTransfer.MAXIMUM_PROGRESS_100) { awakeProgressManager.setProgress(current); } } } /** * displays a message if no proxu used */ private void displayErrroMessageIfNoProxySet() { if (existsAwakeProxyTxt()) { String message = "WARNING: No Proxy in use for this HttpClient Session! " + CR_LF + "Click Yes to exit Java, No to continue."; System.err.println(new Date() + " " + message); } } public String recv() { if (m_responseBody == null) { m_responseBody = ""; } m_responseBody = m_responseBody.trim(); return m_responseBody; } /** * Defines if the result is to be received into a text file
* Call getReceiveFile() to get the file name
* Defaults to false. * * @param receiveInFile * if true, the result will be defined in a file */ public void setReceiveInFile(boolean doReceiveInFile) { this.doReceiveInFile = doReceiveInFile; } /** * @return the receiveFile */ public File getReceiveFile() { return receiveFile; } /** * Test if a user.dir/awake_proxy.txt file exists * * @return true if a user.dir/awake_proxy.txt file exists */ private static boolean existsAwakeProxyTxt() { String userHome = AwakeFileUtil.getUserHome(); if (!userHome.endsWith(File.separator)) { userHome += File.separator; } File proxyFile = new File(userHome + "awake_proxy.txt"); if (proxyFile.exists()) { return true; } else { return false; } } /** * debug tool */ private static void debug(String s) { if (DEBUG) { AwakeClientLogger.log(s); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy