Return-Path: Delivered-To: apmail-hc-commits-archive@www.apache.org Received: (qmail 83979 invoked from network); 28 Dec 2010 15:24:19 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 28 Dec 2010 15:24:19 -0000 Received: (qmail 5131 invoked by uid 500); 28 Dec 2010 15:24:19 -0000 Delivered-To: apmail-hc-commits-archive@hc.apache.org Received: (qmail 5081 invoked by uid 500); 28 Dec 2010 15:24:18 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 5074 invoked by uid 99); 28 Dec 2010 15:24:18 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Dec 2010 15:24:18 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED,T_FRT_STOCK2 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Dec 2010 15:24:15 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 7349523889E3; Tue, 28 Dec 2010 15:23:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1053368 - in /httpcomponents/httpasyncclient/trunk: ./ src/examples/org/apache/http/examples/nio/client/ src/main/java/org/apache/http/impl/nio/client/ src/main/java/org/apache/http/impl/nio/conn/ src/main/java/org/apache/http/nio/client/ ... Date: Tue, 28 Dec 2010 15:23:55 -0000 To: commits@hc.apache.org From: olegk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101228152355.7349523889E3@eris.apache.org> Author: olegk Date: Tue Dec 28 15:23:54 2010 New Revision: 1053368 URL: http://svn.apache.org/viewvc?rev=1053368&view=rev Log: Support for complex (proxied) routes and SSL tunneling Added: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java (with props) httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java (with props) Modified: httpcomponents/httpasyncclient/trunk/pom.xml httpcomponents/httpasyncclient/trunk/src/examples/org/apache/http/examples/nio/client/AsyncClientRequest.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncClient.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/HttpExchange.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/InternalClientEventDispatch.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpSessionPool.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncClient.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java Modified: httpcomponents/httpasyncclient/trunk/pom.xml URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/pom.xml?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/pom.xml (original) +++ httpcomponents/httpasyncclient/trunk/pom.xml Tue Dec 28 15:23:54 2010 @@ -35,6 +35,7 @@ httpasyncclient HttpAsyncClient + 4.0-alpha1-SNAPSHOT HttpComponents Async HttpClient Modified: httpcomponents/httpasyncclient/trunk/src/examples/org/apache/http/examples/nio/client/AsyncClientRequest.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/examples/org/apache/http/examples/nio/client/AsyncClientRequest.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/examples/org/apache/http/examples/nio/client/AsyncClientRequest.java (original) +++ httpcomponents/httpasyncclient/trunk/src/examples/org/apache/http/examples/nio/client/AsyncClientRequest.java Tue Dec 28 15:23:54 2010 @@ -33,35 +33,13 @@ import java.util.concurrent.Future; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.impl.nio.client.BasicHttpAsyncClient; -import org.apache.http.impl.nio.conn.PoolingClientConnectionManager; -import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.message.BasicHttpRequest; import org.apache.http.nio.client.HttpAsyncClient; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpParams; -import org.apache.http.params.SyncBasicHttpParams; public class AsyncClientRequest { public static void main(String[] args) throws Exception { - HttpParams params = new SyncBasicHttpParams(); - params - .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000) - .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000) - .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) - .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) - .setParameter(CoreProtocolPNames.USER_AGENT, "HttpComponents/1.1"); - DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(1, params); - PoolingClientConnectionManager sessmrg = new PoolingClientConnectionManager(ioReactor, params); - sessmrg.setTotalMax(5); - sessmrg.setDefaultMaxPerHost(3); - - HttpAsyncClient httpclient = new BasicHttpAsyncClient( - ioReactor, - sessmrg, - params); - + HttpAsyncClient httpclient = new BasicHttpAsyncClient(); httpclient.start(); try { HttpHost target = new HttpHost("www.apache.org", 80); Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncClient.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncClient.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncClient.java Tue Dec 28 15:23:54 2010 @@ -39,6 +39,8 @@ import org.apache.http.HttpResponse; import org.apache.http.conn.routing.HttpRoutePlanner; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.nio.conn.DefaultHttpAsyncRoutePlanner; +import org.apache.http.impl.nio.conn.PoolingClientConnectionManager; +import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.client.HttpAsyncRequestProducer; import org.apache.http.nio.client.HttpAsyncResponseConsumer; @@ -70,11 +72,12 @@ public class BasicHttpAsyncClient implem private final ClientConnectionManager connmgr; private Thread reactorThread; + private volatile Exception ex; public BasicHttpAsyncClient( final ConnectingIOReactor ioReactor, final ClientConnectionManager connmgr, - final HttpParams params) throws IOReactorException { + final HttpParams params) { super(); this.log = LogFactory.getLog(getClass()); if (params != null) { @@ -86,6 +89,29 @@ public class BasicHttpAsyncClient implem this.connmgr = connmgr; } + public BasicHttpAsyncClient( + final HttpParams params) throws IOReactorException { + super(); + this.log = LogFactory.getLog(getClass()); + if (params != null) { + this.params = params; + } else { + this.params = createDefaultHttpParams(); + } + this.ioReactor = new DefaultConnectingIOReactor(2, this.params); + this.connmgr = new PoolingClientConnectionManager(this.ioReactor); + } + + public BasicHttpAsyncClient() throws IOReactorException { + this(null); + } + + public BasicHttpAsyncClient( + final ConnectingIOReactor ioReactor, + final ClientConnectionManager connmgr) throws IOReactorException { + this(ioReactor, connmgr, null); + } + protected ClientConnectionManager getConnectionManager() { return this.connmgr; } @@ -124,18 +150,27 @@ public class BasicHttpAsyncClient implem private void doExecute() { NHttpClientProtocolHandler handler = new NHttpClientProtocolHandler( createConnectionReuseStrategy()); - IOEventDispatch ioEventDispatch = new InternalClientEventDispatch(handler); try { + IOEventDispatch ioEventDispatch = new InternalClientEventDispatch(handler); this.ioReactor.execute(ioEventDispatch); - } catch (IOException ex) { + } catch (Exception ex) { this.log.error("I/O reactor terminated abnormally", ex); + this.ex = ex; } } + public HttpParams getParams() { + return this.params; + } + public IOReactorStatus getStatus() { return this.ioReactor.getStatus(); } + public Exception getException() { + return this.ex; + } + public synchronized void start() { this.reactorThread = new Thread() { Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/DefaultAsyncRequestDirector.java Tue Dec 28 15:23:54 2010 @@ -156,7 +156,6 @@ class DefaultAsyncRequestDirector imp switch (step) { case HttpRouteDirector.CONNECT_TARGET: case HttpRouteDirector.CONNECT_PROXY: - this.managedConn.updateOpen(this.route); break; case HttpRouteDirector.TUNNEL_TARGET: this.log.debug("Tunnel required"); @@ -167,7 +166,7 @@ class DefaultAsyncRequestDirector imp case HttpRouteDirector.TUNNEL_PROXY: throw new HttpException("Proxy chains are not supported"); case HttpRouteDirector.LAYER_PROTOCOL: - managedConn.updateLayered(); + managedConn.layerProtocol(this.localContext, this.params); break; case HttpRouteDirector.UNREACHABLE: throw new HttpException("Unable to establish route: " + @@ -235,7 +234,7 @@ class DefaultAsyncRequestDirector imp if (!this.routeEstablished) { if (this.current.getMethod().equalsIgnoreCase("CONNECT") && status == HttpStatus.SC_OK) { - this.managedConn.updateTunnelTarget(); + this.managedConn.tunnelTarget(this.params); } else { this.response = response; } @@ -253,7 +252,7 @@ class DefaultAsyncRequestDirector imp if (this.response != null) { this.responseConsumer.consumeContent(decoder, ioctrl); } else { - this.log.debug("Discard intermediate response cocntent"); + this.log.debug("Discard intermediate response content"); } } @@ -328,10 +327,20 @@ class DefaultAsyncRequestDirector imp if (this.log.isDebugEnabled()) { this.log.debug("Connection request suceeded: " + conn); } - this.managedConn = conn; - this.managedConn.getContext().setAttribute(HTTP_EXCHANGE_HANDLER, this); - this.managedConn.requestOutput(); - this.routeEstablished = this.route.equals(conn.getRoute()); + try { + if (!conn.isOpen()) { + conn.open(this.route, this.localContext, this.params); + } + this.managedConn = conn; + this.managedConn.getContext().setAttribute(HTTP_EXCHANGE_HANDLER, this); + this.managedConn.requestOutput(); + this.routeEstablished = this.route.equals(conn.getRoute()); + } catch (IOException ex) { + failed(ex); + } catch (RuntimeException runex) { + failed(runex); + throw runex; + } } private synchronized void connectionRequestFailed(final Exception ex) { Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/HttpExchange.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/HttpExchange.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/HttpExchange.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/HttpExchange.java Tue Dec 28 15:23:54 2010 @@ -108,7 +108,6 @@ class HttpExchange { public void reset() { resetInput(); resetOutput(); - this.handler = null; } public boolean isValid() { Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/InternalClientEventDispatch.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/InternalClientEventDispatch.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/InternalClientEventDispatch.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/InternalClientEventDispatch.java Tue Dec 28 15:23:54 2010 @@ -26,8 +26,11 @@ */ package org.apache.http.impl.nio.client; +import java.io.IOException; + +import org.apache.http.impl.nio.reactor.SSLIOSession; import org.apache.http.nio.NHttpClientHandler; -import org.apache.http.nio.NHttpClientIOTarget; +import org.apache.http.nio.conn.OperatedClientConnection; import org.apache.http.nio.reactor.IOEventDispatch; import org.apache.http.nio.reactor.IOSession; import org.apache.http.protocol.ExecutionContext; @@ -41,46 +44,83 @@ class InternalClientEventDispatch implem this.handler = handler; } - private NHttpClientIOTarget getConnection(final IOSession session) { - return (NHttpClientIOTarget) session.getAttribute(ExecutionContext.HTTP_CONNECTION); + private OperatedClientConnection getConnection(final IOSession session) { + return (OperatedClientConnection) session.getAttribute(ExecutionContext.HTTP_CONNECTION); } - private void assertValid(final NHttpClientIOTarget conn) { + private void assertValid(final OperatedClientConnection conn) { if (conn == null) { throw new IllegalStateException("HTTP connection is null"); } } public void connected(final IOSession session) { - NHttpClientIOTarget conn = getConnection(session); + OperatedClientConnection conn = getConnection(session); assertValid(conn); Object attachment = session.getAttribute(IOSession.ATTACHMENT_KEY); this.handler.connected(conn, attachment); } public void disconnected(final IOSession session) { - NHttpClientIOTarget conn = getConnection(session); + OperatedClientConnection conn = getConnection(session); if (conn != null) { this.handler.closed(conn); } } public void inputReady(final IOSession session) { - NHttpClientIOTarget conn = getConnection(session); + OperatedClientConnection conn = getConnection(session); assertValid(conn); - conn.consumeInput(this.handler); + SSLIOSession ssliosession = conn.getSSLIOSession(); + if (ssliosession == null) { + conn.consumeInput(this.handler); + } else { + try { + if (ssliosession.isAppInputReady()) { + conn.consumeInput(this.handler); + } + ssliosession.inboundTransport(); + } catch (IOException ex) { + this.handler.exception(conn, ex); + ssliosession.shutdown(); + } + } } public void outputReady(final IOSession session) { - NHttpClientIOTarget conn = getConnection(session); + OperatedClientConnection conn = getConnection(session); assertValid(conn); - conn.produceOutput(this.handler); + SSLIOSession ssliosession = conn.getSSLIOSession(); + if (ssliosession == null) { + conn.produceOutput(this.handler); + } else { + try { + if (ssliosession.isAppOutputReady()) { + conn.produceOutput(this.handler); + } + ssliosession.outboundTransport(); + } catch (IOException ex) { + this.handler.exception(conn, ex); + ssliosession.shutdown(); + } + } } public void timeout(IOSession session) { - NHttpClientIOTarget conn = getConnection(session); + OperatedClientConnection conn = getConnection(session); if (conn != null) { - this.handler.timeout(conn); + SSLIOSession ssliosession = conn.getSSLIOSession(); + if (ssliosession == null) { + this.handler.timeout(conn); + } else { + this.handler.timeout(conn); + synchronized (ssliosession) { + if (ssliosession.isOutboundDone() && !ssliosession.isInboundDone()) { + // The session failed to terminate cleanly + ssliosession.shutdown(); + } + } + } } } Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/NHttpClientProtocolHandler.java Tue Dec 28 15:23:54 2010 @@ -359,17 +359,27 @@ class NHttpClientProtocolHandler impleme conn.close(); } HttpContext context = conn.getContext(); + HttpRequest request = httpexchange.getRequest(); HttpResponse response = httpexchange.getResponse(); - if (!this.connStrategy.keepAlive(response, context)) { - conn.close(); + + String method = request.getRequestLine().getMethod(); + int status = response.getStatusLine().getStatusCode(); + if (method.equalsIgnoreCase("CONNECT") && status == HttpStatus.SC_OK) { + this.log.debug("CONNECT method succeeded"); + conn.resetInput(); + } else { + if (!this.connStrategy.keepAlive(response, context)) { + conn.close(); + } } if (this.log.isDebugEnabled()) { this.log.debug("Response processed " + formatState(conn, httpexchange)); } handler.responseCompleted(); if (handler.isDone()) { - httpexchange.reset(); + httpexchange.setHandler(null); } + httpexchange.reset(); if (conn.isOpen()) { // Ready for another request conn.requestOutput(); @@ -378,11 +388,15 @@ class NHttpClientProtocolHandler impleme private boolean canResponseHaveBody(final HttpRequest request, final HttpResponse response) { - if (request != null && "HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) { + String method = request.getRequestLine().getMethod(); + int status = response.getStatusLine().getStatusCode(); + + if (method.equalsIgnoreCase("HEAD")) { + return false; + } + if (method.equalsIgnoreCase("CONNECT") && status == HttpStatus.SC_OK) { return false; } - - int status = response.getStatusLine().getStatusCode(); return status >= HttpStatus.SC_OK && status != HttpStatus.SC_NO_CONTENT && status != HttpStatus.SC_NOT_MODIFIED Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/ClientConnAdaptor.java Tue Dec 28 15:23:54 2010 @@ -33,9 +33,13 @@ import org.apache.http.HttpException; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.conn.routing.RouteTracker; +import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.conn.ConnectionShutdownException; +import org.apache.http.impl.nio.reactor.SSLIOSession; +import org.apache.http.impl.nio.reactor.SSLMode; import org.apache.http.nio.NHttpConnection; import org.apache.http.nio.conn.ClientConnectionManager; import org.apache.http.nio.conn.ManagedClientConnection; @@ -43,6 +47,10 @@ import org.apache.http.nio.conn.Operated import org.apache.http.nio.conn.scheme.LayeringStrategy; import org.apache.http.nio.conn.scheme.Scheme; import org.apache.http.nio.reactor.IOSession; +import org.apache.http.nio.util.ByteBufferAllocator; +import org.apache.http.nio.util.HeapByteBufferAllocator; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.ExecutionContext; import org.apache.http.protocol.HttpContext; class ClientConnAdaptor implements ManagedClientConnection { @@ -55,14 +63,16 @@ class ClientConnAdaptor implements Manag public ClientConnAdaptor( final ClientConnectionManager manager, - final HttpPoolEntry entry, - final OperatedClientConnection conn) { + final HttpPoolEntry entry) { super(); this.manager = manager; this.entry = entry; - this.conn = conn; this.released = false; this.reusable = true; + + IOSession iosession = entry.getIOSession(); + this.conn = (OperatedClientConnection) iosession.getAttribute( + ExecutionContext.HTTP_CONNECTION); } protected ClientConnectionManager getManager() { @@ -136,20 +146,28 @@ class ClientConnAdaptor implements Manag releaseConnection(); } - public boolean isOpen() { - return !this.released; - } - - public boolean isStale() { - return !this.released; - } - private void assertValid() { if (this.released) { throw new ConnectionShutdownException(); } } + private OperatedClientConnection getWrappedConnection() { + OperatedClientConnection conn = this.conn; + if (conn == null) { + throw new ConnectionShutdownException(); + } + return conn; + } + + public synchronized boolean isOpen() { + return !this.released && this.conn != null; + } + + public boolean isStale() { + return isOpen(); + } + public HttpRoute getRoute() { assertValid(); return this.entry.getEffectiveRoute(); @@ -157,104 +175,139 @@ class ClientConnAdaptor implements Manag public synchronized HttpConnectionMetrics getMetrics() { assertValid(); - return this.conn.getMetrics(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.getMetrics(); } public synchronized int getSocketTimeout() { assertValid(); - return this.conn.getSocketTimeout(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.getSocketTimeout(); } public synchronized void setSocketTimeout(int timeout) { assertValid(); - this.conn.setSocketTimeout(timeout); + OperatedClientConnection conn = getWrappedConnection(); + conn.setSocketTimeout(timeout); } - public int getStatus() { - return this.released ? NHttpConnection.CLOSED : NHttpConnection.ACTIVE; + public synchronized int getStatus() { + return this.conn == null || !this.conn.isOpen() ? + NHttpConnection.CLOSED : NHttpConnection.ACTIVE; } public synchronized HttpContext getContext() { assertValid(); - return this.conn.getContext(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.getContext(); } public synchronized HttpRequest getHttpRequest() { assertValid(); - return this.conn.getHttpRequest(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.getHttpRequest(); } public synchronized HttpResponse getHttpResponse() { assertValid(); - return this.conn.getHttpResponse(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.getHttpResponse(); } public synchronized void requestInput() { assertValid(); - this.conn.requestInput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.requestInput(); } public synchronized void requestOutput() { assertValid(); - this.conn.requestOutput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.requestOutput(); } public synchronized void suspendInput() { assertValid(); - this.conn.suspendInput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.suspendInput(); } public synchronized void suspendOutput() { assertValid(); - this.conn.suspendOutput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.suspendOutput(); } public synchronized boolean isRequestSubmitted() { assertValid(); - return this.conn.isRequestSubmitted(); + OperatedClientConnection conn = getWrappedConnection(); + return conn.isRequestSubmitted(); } public synchronized void resetInput() { assertValid(); - this.conn.resetInput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.resetInput(); } public synchronized void resetOutput() { assertValid(); - this.conn.resetOutput(); + OperatedClientConnection conn = getWrappedConnection(); + conn.resetOutput(); } public synchronized void submitRequest( final HttpRequest request) throws IOException, HttpException { assertValid(); - this.conn.submitRequest(request); + OperatedClientConnection conn = getWrappedConnection(); + conn.submitRequest(request); + } + + protected ByteBufferAllocator createByteBufferAllocator() { + return new HeapByteBufferAllocator(); } - public synchronized void updateOpen(final HttpRoute route) { + protected HttpResponseFactory createHttpResponseFactory() { + return new DefaultHttpResponseFactory(); + } + + public synchronized void open( + final HttpRoute route, + final HttpContext context, final HttpParams params) throws IOException { assertValid(); RouteTracker tracker = this.entry.getTracker(); if (tracker.isConnected()) { throw new IllegalStateException("Connection already open"); } + HttpHost target = route.getTargetHost(); HttpHost proxy = route.getProxyHost(); + IOSession iosession = this.entry.getIOSession(); + if (proxy == null) { Scheme scheme = this.manager.getSchemeRegistry().getScheme(target); LayeringStrategy layeringStrategy = scheme.getLayeringStrategy(); if (layeringStrategy != null) { - IOSession iosession = this.entry.getIOSession(); - iosession = layeringStrategy.layer(iosession); - this.conn.upgrade(iosession); - tracker.connectTarget(layeringStrategy.isSecure()); - } else { - tracker.connectTarget(false); + SSLIOSession ssliosession = (SSLIOSession) layeringStrategy.layer(iosession); + ssliosession.bind(SSLMode.CLIENT, params); + iosession = ssliosession; } + } + + OperatedClientConnection conn = new DefaultClientConnection( + iosession, createHttpResponseFactory(), createByteBufferAllocator(), params); + iosession.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); + + this.conn = conn; + if (proxy == null) { + tracker.connectTarget(conn.getSSLIOSession() != null); } else { tracker.connectProxy(proxy, false); } } - public synchronized void updateTunnelProxy(final HttpHost next){ + public synchronized void tunnelProxy( + final HttpHost next, final HttpParams params) throws IOException { assertValid(); RouteTracker tracker = this.entry.getTracker(); if (!tracker.isConnected()) { @@ -263,7 +316,8 @@ class ClientConnAdaptor implements Manag tracker.tunnelProxy(next, false); } - public synchronized void updateTunnelTarget() { + public synchronized void tunnelTarget( + final HttpParams params) throws IOException { assertValid(); RouteTracker tracker = this.entry.getTracker(); if (!tracker.isConnected()) { @@ -275,8 +329,10 @@ class ClientConnAdaptor implements Manag tracker.tunnelTarget(false); } - public synchronized void updateLayered(){ + public synchronized void layerProtocol( + final HttpContext context, final HttpParams params) throws IOException { assertValid(); + OperatedClientConnection conn = getWrappedConnection(); RouteTracker tracker = this.entry.getTracker(); if (!tracker.isConnected()) { throw new IllegalStateException("Connection not open"); @@ -295,8 +351,10 @@ class ClientConnAdaptor implements Manag " scheme does not provider support for protocol layering"); } IOSession iosession = this.entry.getIOSession(); - iosession = layeringStrategy.layer(iosession); - this.conn.upgrade(iosession); + SSLIOSession ssliosession = (SSLIOSession) layeringStrategy.layer(iosession); + ssliosession.bind(SSLMode.CLIENT, params); + + conn.upgrade(ssliosession); tracker.layerProtocol(layeringStrategy.isSecure()); } Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java Tue Dec 28 15:23:54 2010 @@ -37,6 +37,7 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseFactory; import org.apache.http.impl.nio.DefaultNHttpClientConnection; +import org.apache.http.impl.nio.reactor.SSLIOSession; import org.apache.http.nio.NHttpMessageParser; import org.apache.http.nio.NHttpMessageWriter; import org.apache.http.nio.conn.OperatedClientConnection; @@ -53,6 +54,8 @@ public class DefaultClientConnection private final Log wirelog = LogFactory.getLog("org.apache.http.wire"); private final Log log; + private SSLIOSession ssliosession; + public DefaultClientConnection( final IOSession iosession, final HttpResponseFactory responseFactory, @@ -60,16 +63,33 @@ public class DefaultClientConnection final HttpParams params) { super(iosession, responseFactory, allocator, params); this.log = LogFactory.getLog(iosession.getClass()); - upgrade(iosession); + if (this.log.isDebugEnabled() || this.wirelog.isDebugEnabled()) { + this.session = new LoggingIOSession(iosession, this.log, this.wirelog); + } + if (iosession instanceof SSLIOSession) { + this.ssliosession = (SSLIOSession) iosession; + } else { + this.ssliosession = null; + } } public void upgrade(final IOSession iosession) { + this.session.setBufferStatus(null); if (this.log.isDebugEnabled() || this.wirelog.isDebugEnabled()) { - this.session = new LoggingIOSession( - iosession, this.headerlog, this.wirelog); + this.session = new LoggingIOSession(iosession, this.headerlog, this.wirelog); } else { this.session = iosession; } + this.session.setBufferStatus(this); + if (iosession instanceof SSLIOSession) { + this.ssliosession = (SSLIOSession) iosession; + } else { + this.ssliosession = null; + } + } + + public SSLIOSession getSSLIOSession() { + return this.ssliosession; } @Override Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpSessionPool.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpSessionPool.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpSessionPool.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpSessionPool.java Tue Dec 28 15:23:54 2010 @@ -63,11 +63,14 @@ class HttpSessionPool extends SessionPoo } public SocketAddress resolveRemoteAddress(final HttpRoute route) { - HttpHost target = route.getTargetHost(); - String hostname = target.getHostName(); - int port = target.getPort(); + HttpHost firsthop = route.getProxyHost(); + if (firsthop == null) { + firsthop = route.getTargetHost(); + } + String hostname = firsthop.getHostName(); + int port = firsthop.getPort(); if (port < 0) { - Scheme scheme = this.schemeRegistry.getScheme(target); + Scheme scheme = this.schemeRegistry.getScheme(firsthop); port = scheme.resolvePort(port); } return new InetSocketAddress(hostname, port); Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java Tue Dec 28 15:23:54 2010 @@ -31,23 +31,16 @@ import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpResponseFactory; import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.nio.pool.PoolEntryCallback; import org.apache.http.nio.concurrent.BasicFuture; import org.apache.http.nio.concurrent.FutureCallback; import org.apache.http.nio.conn.ManagedClientConnection; import org.apache.http.nio.conn.ClientConnectionManager; -import org.apache.http.nio.conn.OperatedClientConnection; import org.apache.http.nio.conn.PoolStats; import org.apache.http.nio.conn.scheme.SchemeRegistry; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.nio.reactor.IOSession; -import org.apache.http.nio.util.ByteBufferAllocator; -import org.apache.http.nio.util.HeapByteBufferAllocator; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.ExecutionContext; public class PoolingClientConnectionManager implements ClientConnectionManager { @@ -55,22 +48,24 @@ public class PoolingClientConnectionMana private final HttpSessionPool pool; private final SchemeRegistry schemeRegistry; - private final HttpParams params; public PoolingClientConnectionManager( final ConnectingIOReactor ioreactor, - final SchemeRegistry schemeRegistry, - final HttpParams params) { + final SchemeRegistry schemeRegistry) { super(); if (ioreactor == null) { throw new IllegalArgumentException("I/O reactor may not be null"); } - if (params == null) { - throw new IllegalArgumentException("HTTP parameters may not be null"); + if (schemeRegistry == null) { + throw new IllegalArgumentException("Scheme registory may not be null"); } this.pool = new HttpSessionPool(ioreactor, schemeRegistry); this.schemeRegistry = schemeRegistry; - this.params = params; + } + + public PoolingClientConnectionManager( + final ConnectingIOReactor ioreactor) { + this(ioreactor, SchemeRegistryFactory.createDefault()); } public SchemeRegistry getSchemeRegistry() { @@ -152,14 +147,6 @@ public class PoolingClientConnectionMana this.pool.shutdown(); } - protected ByteBufferAllocator createByteBufferAllocator() { - return new HeapByteBufferAllocator(); - } - - protected HttpResponseFactory createHttpResponseFactory() { - return new DefaultHttpResponseFactory(); - } - class InternalPoolEntryCallback implements PoolEntryCallback { private final BasicFuture future; @@ -174,22 +161,10 @@ public class PoolingClientConnectionMana if (log.isDebugEnabled()) { log.debug("I/O session allocated: " + entry); } - IOSession iosession = entry.getIOSession(); - OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute( - ExecutionContext.HTTP_CONNECTION); - if (conn == null) { - conn = new DefaultClientConnection( - iosession, - createHttpResponseFactory(), - createByteBufferAllocator(), - params); - iosession.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); - } - ClientConnAdaptor result = new ClientConnAdaptor( + ManagedClientConnection conn = new ClientConnAdaptor( PoolingClientConnectionManager.this, - entry, - conn); - if (!this.future.completed(result)) { + entry); + if (!this.future.completed(conn)) { pool.release(entry, true); } } Added: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java?rev=1053368&view=auto ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java (added) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java Tue Dec 28 15:23:54 2010 @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.nio.conn; + +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.nio.conn.scheme.Scheme; +import org.apache.http.nio.conn.scheme.SchemeRegistry; +import org.apache.http.nio.conn.ssl.SSLLayeringStrategy; + +/** + * @since 4.1 + */ +@ThreadSafe +public final class SchemeRegistryFactory { + + public static SchemeRegistry createDefault() { + SchemeRegistry registry = new SchemeRegistry(); + registry.register( + new Scheme("http", 80, null)); + registry.register( + new Scheme("https", 443, SSLLayeringStrategy.getLayeringStrategy())); + return registry; + } + +} + Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/SchemeRegistryFactory.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncClient.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncClient.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncClient.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncClient.java Tue Dec 28 15:23:54 2010 @@ -33,6 +33,7 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.nio.concurrent.FutureCallback; import org.apache.http.nio.reactor.IOReactorStatus; +import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; public interface HttpAsyncClient { @@ -43,6 +44,8 @@ public interface HttpAsyncClient { IOReactorStatus getStatus(); + HttpParams getParams(); + Future execute( HttpAsyncRequestProducer requestProducer, HttpAsyncResponseConsumer responseConsumer, Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java Tue Dec 28 15:23:54 2010 @@ -26,15 +26,19 @@ */ package org.apache.http.nio.conn; +import java.io.IOException; + import org.apache.http.HttpHost; import org.apache.http.conn.ConnectionReleaseTrigger; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.nio.NHttpClientConnection; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; public interface ManagedClientConnection extends NHttpClientConnection, ConnectionReleaseTrigger { HttpRoute getRoute(); - + Object getState(); void setState(Object state); @@ -44,13 +48,13 @@ public interface ManagedClientConnection void markNonReusable(); boolean isReusable(); - - void updateOpen(HttpRoute route); - - void updateTunnelTarget(); - - void updateTunnelProxy(HttpHost next); - - void updateLayered(); - + + void open(HttpRoute route, HttpContext context, HttpParams params) throws IOException; + + void tunnelTarget(HttpParams params) throws IOException; + + void tunnelProxy(HttpHost next, HttpParams params) throws IOException; + + void layerProtocol(HttpContext context, HttpParams params) throws IOException; + } Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java Tue Dec 28 15:23:54 2010 @@ -26,11 +26,15 @@ */ package org.apache.http.nio.conn; +import org.apache.http.impl.nio.reactor.SSLIOSession; import org.apache.http.nio.NHttpClientConnection; +import org.apache.http.nio.NHttpClientIOTarget; import org.apache.http.nio.reactor.IOSession; -public interface OperatedClientConnection extends NHttpClientConnection { +public interface OperatedClientConnection extends NHttpClientConnection, NHttpClientIOTarget { void upgrade(IOSession iosession); + SSLIOSession getSSLIOSession(); + } Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java (original) +++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java Tue Dec 28 15:23:54 2010 @@ -60,6 +60,12 @@ public class SSLLayeringStrategy impleme public static final String SSL = "SSL"; public static final String SSLV2 = "SSLv2"; + private static final SSLLayeringStrategy DEFAULT_STRATEGY = new SSLLayeringStrategy(); + + public static SSLLayeringStrategy getLayeringStrategy() { + return DEFAULT_STRATEGY; + } + private final SSLContext sslContext; private final X509HostnameVerifier hostnameVerifier; @@ -94,6 +100,14 @@ public class SSLLayeringStrategy impleme return sslcontext; } + private static SSLContext createDefaultSSLContext() { + try { + return createSSLContext(TLS, null, null, null, null, null); + } catch (Exception ex) { + throw new IllegalStateException("Failure initializing default SSL context", ex); + } + } + public SSLLayeringStrategy( final String algorithm, final KeyStore keystore, @@ -166,11 +180,15 @@ public class SSLLayeringStrategy impleme this(sslContext, new BrowserCompatHostnameVerifier()); } + private SSLLayeringStrategy() { + this(createDefaultSSLContext()); + } + public boolean isSecure() { return true; } - public IOSession layer(final IOSession iosession) { + public SSLIOSession layer(final IOSession iosession) { return new SSLIOSession(iosession, this.sslContext, new InternalSSLSetupHandler()); } Modified: httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java?rev=1053368&r1=1053367&r2=1053368&view=diff ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java (original) +++ httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java Tue Dec 28 15:23:54 2010 @@ -22,10 +22,7 @@ import org.apache.http.nio.conn.scheme.S import org.apache.http.nio.conn.scheme.SchemeRegistry; import org.apache.http.nio.entity.NByteArrayEntity; import org.apache.http.nio.reactor.ConnectingIOReactor; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.CoreProtocolPNames; -import org.apache.http.params.HttpParams; -import org.apache.http.params.SyncBasicHttpParams; +import org.apache.http.params.BasicHttpParams; import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Assert; @@ -45,19 +42,11 @@ public class TestHttpAsync extends Serve int port = this.localServer.getServiceAddress().getPort(); this.target = new HttpHost("localhost", port); - HttpParams params = new SyncBasicHttpParams(); - params - .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000) - .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000) - .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) - .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) - .setParameter(CoreProtocolPNames.USER_AGENT, "HttpComponents/1.1"); - - ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, params); + ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, new BasicHttpParams()); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", 80, null)); - this.sessionManager = new PoolingClientConnectionManager(ioReactor, schemeRegistry, params); - this.httpclient = new BasicHttpAsyncClient(ioReactor, this.sessionManager, params); + this.sessionManager = new PoolingClientConnectionManager(ioReactor, schemeRegistry); + this.httpclient = new BasicHttpAsyncClient(ioReactor, this.sessionManager); } @After @@ -162,7 +151,7 @@ public class TestHttpAsync extends Serve } @Test - public void testMultipleRequestFailures() throws Exception { + public void testRequestFailure() throws Exception { this.httpclient.start(); HttpGet httpget = new HttpGet("/random/2048"); Added: httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java?rev=1053368&view=auto ============================================================================== --- httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java (added) +++ httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java Tue Dec 28 15:23:54 2010 @@ -0,0 +1,235 @@ +package org.apache.http.impl.nio.client; + +import java.io.IOException; +import java.net.URL; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.nio.conn.PoolingClientConnectionManager; +import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; +import org.apache.http.localserver.LocalTestServer; +import org.apache.http.localserver.ServerTestBase; +import org.apache.http.nio.ContentDecoder; +import org.apache.http.nio.IOControl; +import org.apache.http.nio.client.HttpAsyncClient; +import org.apache.http.nio.conn.scheme.Scheme; +import org.apache.http.nio.conn.scheme.SchemeRegistry; +import org.apache.http.nio.conn.ssl.SSLLayeringStrategy; +import org.apache.http.nio.entity.NByteArrayEntity; +import org.apache.http.nio.reactor.ConnectingIOReactor; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.util.EntityUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class TestHttpsAsync extends ServerTestBase { + + private SSLContext serverSSLContext; + private SSLContext clientSSLContext; + private HttpHost target; + private PoolingClientConnectionManager sessionManager; + private HttpAsyncClient httpclient; + + private KeyManagerFactory createKeyManagerFactory() throws NoSuchAlgorithmException { + String algo = KeyManagerFactory.getDefaultAlgorithm(); + try { + return KeyManagerFactory.getInstance(algo); + } catch (NoSuchAlgorithmException ex) { + return KeyManagerFactory.getInstance("SunX509"); + } + } + + private TrustManagerFactory createTrustManagerFactory() throws NoSuchAlgorithmException { + String algo = TrustManagerFactory.getDefaultAlgorithm(); + try { + return TrustManagerFactory.getInstance(algo); + } catch (NoSuchAlgorithmException ex) { + return TrustManagerFactory.getInstance("SunX509"); + } + } + + @Before + public void setUp() throws Exception { + super.setUp(); + + ClassLoader cl = getClass().getClassLoader(); + URL url = cl.getResource("test.keystore"); + KeyStore keystore = KeyStore.getInstance("jks"); + char[] pwd = "nopassword".toCharArray(); + keystore.load(url.openStream(), pwd); + + TrustManagerFactory tmf = createTrustManagerFactory(); + tmf.init(keystore); + TrustManager[] tm = tmf.getTrustManagers(); + + KeyManagerFactory kmfactory = createKeyManagerFactory(); + kmfactory.init(keystore, pwd); + KeyManager[] km = kmfactory.getKeyManagers(); + + this.serverSSLContext = SSLContext.getInstance("TLS"); + this.serverSSLContext.init(km, tm, null); + + this.clientSSLContext = SSLContext.getInstance("TLS"); + this.clientSSLContext.init(null, tm, null); + + this.localServer = new LocalTestServer(this.serverSSLContext); + this.localServer.registerDefaultHandlers(); + this.localServer.start(); + int port = this.localServer.getServiceAddress().getPort(); + this.target = new HttpHost("localhost", port, "https"); + + ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, new BasicHttpParams()); + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, null)); + schemeRegistry.register(new Scheme("https", 443, new SSLLayeringStrategy(this.clientSSLContext))); + this.sessionManager = new PoolingClientConnectionManager(ioReactor, schemeRegistry); + this.httpclient = new BasicHttpAsyncClient(ioReactor, this.sessionManager); + } + + @After + public void tearDown() throws Exception { + this.httpclient.shutdown(); + super.tearDown(); + } + + @Test + public void testSingleGet() throws Exception { + this.httpclient.start(); + HttpGet httpget = new HttpGet("/random/2048"); + Future future = this.httpclient.execute(this.target, httpget, null); + HttpResponse response = future.get(); + Assert.assertNotNull(response); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + } + + @Test + public void testSinglePost() throws Exception { + byte[] b1 = new byte[1024]; + Random rnd = new Random(System.currentTimeMillis()); + rnd.nextBytes(b1); + + this.httpclient.start(); + + HttpPost httppost = new HttpPost("/echo/stuff"); + httppost.setEntity(new NByteArrayEntity(b1)); + + Future future = this.httpclient.execute(this.target, httppost, null); + HttpResponse response = future.get(); + Assert.assertNotNull(response); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + HttpEntity entity = response.getEntity(); + Assert.assertNotNull(entity); + byte[] b2 = EntityUtils.toByteArray(entity); + Assert.assertArrayEquals(b1, b2); + } + + @Test + public void testMultiplePostsOverMultipleConnections() throws Exception { + byte[] b1 = new byte[1024]; + Random rnd = new Random(System.currentTimeMillis()); + rnd.nextBytes(b1); + + int reqCount = 20; + + this.sessionManager.setDefaultMaxPerHost(reqCount); + this.sessionManager.setTotalMax(100); + this.httpclient.start(); + + Queue> queue = new LinkedList>(); + + for (int i = 0; i < reqCount; i++) { + HttpPost httppost = new HttpPost("/echo/stuff"); + httppost.setEntity(new NByteArrayEntity(b1)); + queue.add(this.httpclient.execute(this.target, httppost, null)); + } + + while (!queue.isEmpty()) { + Future future = queue.remove(); + HttpResponse response = future.get(); + Assert.assertNotNull(response); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + HttpEntity entity = response.getEntity(); + Assert.assertNotNull(entity); + byte[] b2 = EntityUtils.toByteArray(entity); + Assert.assertArrayEquals(b1, b2); + } + } + + @Test + public void testMultiplePostsOverSingleConnection() throws Exception { + byte[] b1 = new byte[1024]; + Random rnd = new Random(System.currentTimeMillis()); + rnd.nextBytes(b1); + + int reqCount = 20; + + this.sessionManager.setDefaultMaxPerHost(1); + this.sessionManager.setTotalMax(100); + this.httpclient.start(); + + Queue> queue = new LinkedList>(); + + for (int i = 0; i < reqCount; i++) { + HttpPost httppost = new HttpPost("/echo/stuff"); + httppost.setEntity(new NByteArrayEntity(b1)); + queue.add(this.httpclient.execute(this.target, httppost, null)); + } + + while (!queue.isEmpty()) { + Future future = queue.remove(); + HttpResponse response = future.get(); + Assert.assertNotNull(response); + Assert.assertEquals(200, response.getStatusLine().getStatusCode()); + HttpEntity entity = response.getEntity(); + Assert.assertNotNull(entity); + byte[] b2 = EntityUtils.toByteArray(entity); + Assert.assertArrayEquals(b1, b2); + } + } + + @Test + public void testRequestFailure() throws Exception { + this.httpclient.start(); + + HttpGet httpget = new HttpGet("/random/2048"); + BasicHttpAsyncRequestProducer requestProducer = new BasicHttpAsyncRequestProducer(this.target, httpget) ; + BasicHttpAsyncResponseConsumer responseConsumer = new BasicHttpAsyncResponseConsumer() { + + @Override + public void consumeContent(final ContentDecoder decoder, final IOControl ioctrl) + throws IOException { + throw new IOException("Kaboom"); + } + + }; + Future future = this.httpclient.execute(requestProducer, responseConsumer, null); + try { + future.get(); + Assert.fail("ExecutionException expected"); + } catch (ExecutionException ex) { + Throwable t = ex.getCause(); + Assert.assertNotNull(t); + Assert.assertTrue(t instanceof IOException); + Assert.assertEquals("Kaboom", t.getMessage()); + } + } + +} Propchange: httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Propchange: httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpsAsync.java ------------------------------------------------------------------------------ svn:mime-type = text/plain