You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2010/12/28 16:23:55 UTC

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/ ...

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 @@
   </parent>
   <artifactId>httpasyncclient</artifactId>
   <name>HttpAsyncClient</name>
+  <version>4.0-alpha1-SNAPSHOT</version>
   <description>
    HttpComponents Async HttpClient
   </description>

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<T> 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<T> 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<T> 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<T> 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<T> 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<HttpRoute, HttpPoolEntry> {
 
         private final BasicFuture<ManagedClientConnection> 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
+ * <http://www.apache.org/>.
+ *
+ */
+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();
+
     <T> Future<T> execute(
             HttpAsyncRequestProducer requestProducer,
             HttpAsyncResponseConsumer<T> 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<HttpResponse> 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<HttpResponse> 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<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
+
+        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<HttpResponse> 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<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
+
+        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<HttpResponse> 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<HttpResponse> 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