package com.dubture.getcomposer.packages; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.params.HttpClientParams; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.nio.reactor.IOReactorException; import com.dubture.getcomposer.httpclient.AsyncClientInterface; import com.dubture.getcomposer.httpclient.DefaultHttpAsyncClient; import com.dubture.getcomposer.httpclient.FutureCallback; public class AsyncDownloader extends AbstractDownloader { private List<HttpGet> httpGets; private AsyncClientInterface client; private int lastSlot; private Log log = LogFactory.getLog(AsyncDownloader.class); public AsyncDownloader() { super(); } public AsyncDownloader(String url) { super(url); } protected void init() { super.init(); httpGets = new ArrayList<HttpGet>(); // start http async client try { client = new DefaultHttpAsyncClient(); client.start(); HttpClientParams.setRedirecting(client.getParams(), false); } catch (IOReactorException e) { log.error(e.getMessage()); } } /** * Starts the async download. The returned number is the internal slot for this download transfer, * which can be used as parameter in abort to stop this specific transfer. * * @return slot */ public int download() { try { //if (url.startsWith("https://packagist.org") || url.startsWith("https://getcomposer.org")) { if (url.startsWith("https://")) { registerSSLContext(client.getBackend()); } final HttpGet httpGet = new HttpGet(url); if (httpGet.isAborted()) { httpGet.abort(); } client.execute(httpGet, new FutureCallback<HttpResponse>() { @Override public void failed(Exception e) { for (DownloadListenerInterface listener : listeners) { listener.errorOccured(e); } } @Override public void completed(HttpResponse response) { for (DownloadListenerInterface listener : listeners) { try { listener.dataReceived(response.getEntity().getContent(), httpGet.getURI().toString()); } catch (Exception e) { listener.errorOccured(e); } } } @Override public void cancelled() { for (DownloadListenerInterface listener : listeners) { listener.aborted(httpGet.getURI().toString()); } } }); httpGets.add(httpGet); // client.shutdown(); lastSlot = httpGets.size() - 1; return lastSlot; } catch (Exception e) { for (DownloadListenerInterface listener : listeners) { listener.errorOccured(e); } } return -1; } private void registerSSLContext(HttpClient client) throws Exception { X509TrustManager tm = new ComposerTrustManager(); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[]{tm}, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientConnectionManager ccm = client.getConnectionManager(); SchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new Scheme("https", 443, ssf)); // implementation for HttpAsyncClient /* X509TrustManager tm = new ComposerTrustManager(); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[]{tm}, null); SSLLayeringStrategy sls = new SSLLayeringStrategy(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); ClientAsyncConnectionManager ccm = client.getConnectionManager(); AsyncSchemeRegistry sr = ccm.getSchemeRegistry(); sr.register(new AsyncScheme("https", 443, sls)); */ } /** * Aborts the last transfer */ public void abort() { abort(lastSlot); } /** * Aborts a transfer at the given slot * * @param slot */ public void abort(int slot) { try { HttpGet httpGet = httpGets.get(slot); httpGet.abort(); abortListeners(httpGet.getURI().toString()); } catch(Exception e) { log.error(e.getMessage()); } } protected void abortListeners(String url) { for (DownloadListenerInterface listener : listeners) { listener.aborted(url); } } /** * Shuts down the download client */ public void shutdown() { try { client.shutdown(); } catch (InterruptedException e) { log.error(e.getMessage()); } } }