hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1050153 [1/2] - in /httpcomponents/httpasyncclient/trunk/src: main/java/org/apache/http/impl/nio/client/ main/java/org/apache/http/impl/nio/conn/ main/java/org/apache/http/impl/nio/pool/ main/java/org/apache/http/nio/client/ main/java/org/...
Date Thu, 16 Dec 2010 20:49:14 GMT
Author: olegk
Date: Thu Dec 16 20:49:14 2010
New Revision: 1050153

URL: http://svn.apache.org/viewvc?rev=1050153&view=rev
Log:
Partial support for complex routes

Added:
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java   (with props)
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/TrustManagerDecorator.java   (with props)
Removed:
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/LoggingNHttpClientConnection.java
Modified:
    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/BasicHttpAsyncResponseConsumer.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/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/DefaultHttpAsyncRoutePlanner.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpPoolEntry.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/LoggingIOSession.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/PoolingClientConnectionManager.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/pool/PoolEntry.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncResponseConsumer.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ClientConnectionManager.java
    httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedClientConnection.java
    httpcomponents/httpasyncclient/trunk/src/test/java/org/apache/http/impl/nio/client/TestHttpAsync.java

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -39,8 +39,6 @@ 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;
@@ -88,16 +86,8 @@ 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, params);
+    protected ClientConnectionManager getConnectionManager() {
+        return this.connmgr;
     }
 
     protected HttpParams createDefaultHttpParams() {
@@ -128,7 +118,7 @@ public class BasicHttpAsyncClient implem
     }
 
     protected HttpRoutePlanner createHttpRoutePlanner() {
-        return new DefaultHttpAsyncRoutePlanner();
+        return new DefaultHttpAsyncRoutePlanner(this.connmgr.getSchemeRegistry());
     }
 
     private void doExecute() {
@@ -178,6 +168,7 @@ public class BasicHttpAsyncClient implem
         DefaultAsyncRequestDirector<T> httpexchange;
         synchronized (this) {
             httpexchange = new DefaultAsyncRequestDirector<T>(
+                    this.log,
                     requestProducer,
                     responseConsumer,
                     context,

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncResponseConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncResponseConsumer.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncResponseConsumer.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/client/BasicHttpAsyncResponseConsumer.java Thu Dec 16 20:49:14 2010
@@ -67,6 +67,16 @@ public class BasicHttpAsyncResponseConsu
         return this.contentConsumingEntity;
     }
 
+    private void releaseResources() {
+        if (this.contentConsumingEntity != null) {
+            try {
+                this.contentConsumingEntity.finish();
+                this.contentConsumingEntity = null;
+            } catch (IOException ex) {
+            }
+        }
+    }
+
     public synchronized void responseReceived(final HttpResponse response) {
         if (this.response != null) {
             throw new IllegalStateException("HTTP response already set");
@@ -78,50 +88,43 @@ public class BasicHttpAsyncResponseConsu
             final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
         ConsumingNHttpEntity consumer = getConsumingHttpEntity();
         consumer.consumeContent(decoder, ioctrl);
-    }
-
-    private void reset() {
-        if (this.contentConsumingEntity != null) {
-            try {
-                this.contentConsumingEntity.finish();
-                this.contentConsumingEntity = null;
-            } catch (IOException ex) {
-            }
+        if (decoder.isCompleted()) {
+            this.response.setEntity(consumer);
+            releaseResources();
         }
     }
 
-    public synchronized void cancel() {
+    public synchronized void responseCompleted() {
         if (this.completed) {
             return;
         }
         this.completed = true;
-        this.response = null;
-        reset();
+        if (this.response != null) {
+            this.result = this.response;
+        }
+        releaseResources();
     }
 
-    public synchronized void failed(final Exception ex) {
+    public synchronized void cancel() {
         if (this.completed) {
             return;
         }
         this.completed = true;
-        this.ex = ex;
         this.response = null;
-        reset();
+        releaseResources();
     }
 
-    public synchronized void completed() {
+    public synchronized void failed(final Exception ex) {
         if (this.completed) {
             return;
         }
         this.completed = true;
-        if (this.response != null) {
-            this.result = this.response;
-            this.result.setEntity(this.contentConsumingEntity);
-        }
-        reset();
+        this.ex = ex;
+        this.response = null;
+        releaseResources();
     }
 
-    public boolean isCompleted() {
+    public boolean isDone() {
         return this.completed;
     }
 
@@ -134,7 +137,7 @@ public class BasicHttpAsyncResponseConsu
     }
 
     public HttpResponse getResult() {
-        return this.response;
+        return this.result;
     }
 
 }

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -32,20 +32,26 @@ import java.net.URISyntaxException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.logging.Log;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
 import org.apache.http.ProtocolException;
+import org.apache.http.ProtocolVersion;
 import org.apache.http.client.params.ClientPNames;
 import org.apache.http.client.protocol.ClientContext;
 import org.apache.http.client.utils.URIUtils;
+import org.apache.http.conn.routing.BasicRouteDirector;
 import org.apache.http.conn.routing.HttpRoute;
+import org.apache.http.conn.routing.HttpRouteDirector;
 import org.apache.http.conn.routing.HttpRoutePlanner;
 import org.apache.http.impl.client.ClientParamsStack;
 import org.apache.http.impl.client.EntityEnclosingRequestWrapper;
 import org.apache.http.impl.client.RequestWrapper;
+import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.IOControl;
@@ -56,17 +62,19 @@ import org.apache.http.nio.concurrent.Ba
 import org.apache.http.nio.concurrent.FutureCallback;
 import org.apache.http.nio.conn.ClientConnectionManager;
 import org.apache.http.nio.conn.ManagedClientConnection;
+import org.apache.http.nio.conn.scheme.Scheme;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
 
 class DefaultAsyncRequestDirector<T> implements HttpAsyncExchangeHandler<T> {
 
-    public static final String HTTP_EXCHANGE_HANDLER    = "http.nio.async-exchange-handler";
-    public static final String HTTP_ROUTE_STATE         = "http.nio.route-state";
-    public static final String HTTP_ROUTE_TRACKER       = "http.nio.route-tracker";
+    public static final String HTTP_EXCHANGE_HANDLER = "http.nio.async-exchange-handler";
+
+    private final Log log;
 
     private final HttpAsyncRequestProducer requestProducer;
     private final HttpAsyncResponseConsumer<T> responseConsumer;
@@ -75,15 +83,20 @@ class DefaultAsyncRequestDirector<T> imp
     private final ClientConnectionManager connmgr;
     private final HttpProcessor httppocessor;
     private final HttpRoutePlanner routePlanner;
+    private final HttpRouteDirector routeDirector;
     private final HttpParams clientParams;
 
-    private HttpRequest originalRequest;
-    private RequestWrapper currentRequest;
+    private ClientParamsStack params;
+    private RequestWrapper request;
+    private RequestWrapper current;
     private HttpRoute route;
+    private boolean routeEstablished;
     private Future<ManagedClientConnection> connFuture;
     private ManagedClientConnection managedConn;
+    private HttpResponse response;
 
     public DefaultAsyncRequestDirector(
+            final Log log,
             final HttpAsyncRequestProducer requestProducer,
             final HttpAsyncResponseConsumer<T> responseConsumer,
             final HttpContext localContext,
@@ -93,6 +106,7 @@ class DefaultAsyncRequestDirector<T> imp
             final HttpRoutePlanner routePlanner,
             final HttpParams clientParams) {
         super();
+        this.log = log;
         this.requestProducer = requestProducer;
         this.responseConsumer = responseConsumer;
         this.localContext = localContext;
@@ -100,22 +114,20 @@ class DefaultAsyncRequestDirector<T> imp
         this.connmgr = connmgr;
         this.httppocessor = httppocessor;
         this.routePlanner = routePlanner;
+        this.routeDirector = new BasicRouteDirector();
         this.clientParams = clientParams;
     }
 
-    public void start() {
+    public synchronized void start() {
         try {
             HttpHost target = this.requestProducer.getTarget();
-            this.originalRequest = this.requestProducer.generateRequest();
-            HttpParams params = new ClientParamsStack(
-                    null, this.clientParams, this.originalRequest.getParams(), null);
-            this.currentRequest = wrapRequest(this.originalRequest);
-            this.currentRequest.setParams(params);
-            this.route = determineRoute(target, this.currentRequest, this.localContext);
-
-            long connectTimeout = HttpConnectionParams.getConnectionTimeout(params);
+            HttpRequest request = this.requestProducer.generateRequest();
+            this.params = new ClientParamsStack(null, this.clientParams, request.getParams(), null);
+            this.request = wrapRequest(request);
+            this.request.setParams(this.params);
+            this.route = determineRoute(target, this.request, this.localContext);
+            long connectTimeout = HttpConnectionParams.getConnectionTimeout(this.params);
             Object userToken = this.localContext.getAttribute(ClientContext.USER_TOKEN);
-
             this.connFuture = this.connmgr.leaseConnection(
                     this.route, userToken,
                     connectTimeout, TimeUnit.MILLISECONDS,
@@ -135,29 +147,66 @@ class DefaultAsyncRequestDirector<T> imp
         return this.requestProducer.getTarget();
     }
 
-    public HttpRequest generateRequest() throws IOException, HttpException {
+    public synchronized HttpRequest generateRequest() throws IOException, HttpException {
+        if (!this.routeEstablished) {
+            int step;
+            do {
+                HttpRoute fact = this.managedConn.getRoute();
+                step = this.routeDirector.nextStep(this.route, fact);
+                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");
+                    HttpRequest connect = createConnectRequest(this.route);
+                    this.current = wrapRequest(connect);
+                    this.current.setParams(this.params);
+                    break;
+                case HttpRouteDirector.TUNNEL_PROXY:
+                    throw new HttpException("Proxy chains are not supported");
+                case HttpRouteDirector.LAYER_PROTOCOL:
+                    managedConn.updateLayered();
+                    break;
+                case HttpRouteDirector.UNREACHABLE:
+                    throw new HttpException("Unable to establish route: " +
+                            "planned = " + this.route + "; current = " + fact);
+                case HttpRouteDirector.COMPLETE:
+                    this.routeEstablished = true;
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown step indicator "
+                            + step + " from RouteDirector.");
+                }
+            } while (step > HttpRouteDirector.COMPLETE && this.current == null);
+        }
 
-        HttpHost target = (HttpHost) this.currentRequest.getParams().getParameter(
-                ClientPNames.VIRTUAL_HOST);
+        HttpHost target = (HttpHost) this.params.getParameter(ClientPNames.VIRTUAL_HOST);
         if (target == null) {
             target = this.route.getTargetHost();
         }
-
         HttpHost proxy = this.route.getProxyHost();
 
+        if (this.current == null) {
+            this.current = this.request;
+            // Re-write request URI if needed
+            rewriteRequestURI(this.current, this.route);
+        }
         // Reset headers on the request wrapper
-        this.currentRequest.resetHeaders();
-        // Re-write request URI if needed
-        rewriteRequestURI(this.currentRequest, this.route);
+        this.current.resetHeaders();
 
-        this.localContext.setAttribute(ExecutionContext.HTTP_REQUEST, this.currentRequest);
+        this.localContext.setAttribute(ExecutionContext.HTTP_REQUEST, this.current);
         this.localContext.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
         this.localContext.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
-        this.httppocessor.process(this.currentRequest, this.localContext);
-        return this.currentRequest;
+        this.httppocessor.process(this.current, this.localContext);
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Request submitted: " + this.current.getRequestLine());
+        }
+        return this.current;
     }
 
-    public void produceContent(
+    public synchronized void produceContent(
             final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
         this.requestProducer.produceContent(encoder, ioctrl);
         if (encoder.isCompleted()) {
@@ -173,80 +222,120 @@ class DefaultAsyncRequestDirector<T> imp
         this.requestProducer.resetRequest();
     }
 
-    public void responseReceived(final HttpResponse response) throws IOException, HttpException {
-        response.setParams(this.currentRequest.getParams());
+    public synchronized void responseReceived(
+            final HttpResponse response) throws IOException, HttpException {
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Response received: " + response.getStatusLine());
+        }
+        response.setParams(this.params);
         this.localContext.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
         this.httppocessor.process(response, this.localContext);
-        this.responseConsumer.responseReceived(response);
+
+        int status = response.getStatusLine().getStatusCode();
+
+        if (!this.routeEstablished) {
+            if (this.current.getMethod().equalsIgnoreCase("CONNECT") && status == HttpStatus.SC_OK) {
+                this.managedConn.updateTunnelTarget();
+            } else {
+                this.response = response;
+            }
+        } else {
+            this.response = response;
+        }
+        if (this.response != null) {
+            this.responseConsumer.responseReceived(response);
+        }
+        this.current = null;
     }
 
-    public void consumeContent(
+    public synchronized void consumeContent(
             final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
-        this.responseConsumer.consumeContent(decoder, ioctrl);
+        if (this.response != null) {
+            this.responseConsumer.consumeContent(decoder, ioctrl);
+        } else {
+            this.log.debug("Discard intermediate response cocntent");
+        }
     }
 
-    public synchronized void completed() {
-        try {
-            if (this.managedConn != null) {
+    private void releaseResources() {
+        if (this.managedConn != null) {
+            try {
                 this.managedConn.releaseConnection();
+            } catch (IOException ioex) {
+                this.log.debug("I/O error releasing connection", ioex);
             }
-            this.managedConn = null;
-            this.requestProducer.resetRequest();
-            this.responseConsumer.completed();
-            this.resultFuture.completed(this.responseConsumer.getResult());
-        } catch (RuntimeException runex) {
-            this.resultFuture.failed(runex);
-            throw runex;
         }
+        this.managedConn = null;
+        if (this.connFuture != null) {
+            this.connFuture.cancel(true);
+            this.connFuture = null;
+        }
+        this.requestProducer.resetRequest();
     }
 
     public synchronized void failed(final Exception ex) {
         try {
-            this.connFuture.cancel(true);
-            if (this.managedConn != null) {
-                this.managedConn.abortConnection();
-            }
-            this.managedConn = null;
-            this.requestProducer.resetRequest();
             this.responseConsumer.failed(ex);
-            this.resultFuture.failed(ex);
+        } finally {
+            try {
+                this.resultFuture.failed(ex);
+            } finally {
+                releaseResources();
+            }
+        }
+    }
+
+    public synchronized void responseCompleted() {
+        this.log.debug("Response completed");
+        try {
+            if (this.response != null) {
+                this.responseConsumer.responseCompleted();
+                if (this.responseConsumer.isDone()) {
+                    this.log.debug("Response processing completed");
+                    this.resultFuture.completed(this.responseConsumer.getResult());
+                    releaseResources();
+                }
+            } else {
+                this.managedConn.requestOutput();
+            }
         } catch (RuntimeException runex) {
-            this.resultFuture.failed(ex);
+            failed(runex);
             throw runex;
         }
     }
 
     public synchronized void cancel() {
+        this.log.debug("HTTP exchange cancelled");
         try {
-            this.connFuture.cancel(true);
-            if (this.managedConn != null) {
-                this.managedConn.abortConnection();
-            }
-            this.managedConn = null;
-            this.requestProducer.resetRequest();
             this.responseConsumer.cancel();
             this.resultFuture.cancel(true);
+            releaseResources();
         } catch (RuntimeException runex) {
-            this.resultFuture.failed(runex);
+            failed(runex);
             throw runex;
         }
     }
 
-    public boolean isCompleted() {
-        return this.responseConsumer.isCompleted();
+    public boolean isDone() {
+        return this.responseConsumer.isDone();
     }
 
     public T getResult() {
         return this.responseConsumer.getResult();
     }
 
-    private synchronized void sessionRequestCompleted(final ManagedClientConnection session) {
-        this.managedConn = session;
+    private synchronized void connectionRequestCompleted(final ManagedClientConnection conn) {
+        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());
     }
 
-    private synchronized void sessionRequestFailed(final Exception ex) {
+    private synchronized void connectionRequestFailed(final Exception ex) {
+        this.log.debug("Connection request failed", ex);
         try {
             this.requestProducer.resetRequest();
             this.responseConsumer.failed(ex);
@@ -255,7 +344,8 @@ class DefaultAsyncRequestDirector<T> imp
         }
     }
 
-    private synchronized void sessionRequestCancelled() {
+    private synchronized void connectionRequestCancelled() {
+        this.log.debug("Connection request cancelled");
         try {
             this.requestProducer.resetRequest();
             this.responseConsumer.cancel();
@@ -267,15 +357,15 @@ class DefaultAsyncRequestDirector<T> imp
     class InternalFutureCallback implements FutureCallback<ManagedClientConnection> {
 
         public void completed(final ManagedClientConnection session) {
-            sessionRequestCompleted(session);
+            connectionRequestCompleted(session);
         }
 
         public void failed(final Exception ex) {
-            sessionRequestFailed(ex);
+            connectionRequestFailed(ex);
         }
 
         public void cancelled() {
-            sessionRequestCancelled();
+            connectionRequestCancelled();
         }
 
     }
@@ -320,9 +410,28 @@ class DefaultAsyncRequestDirector<T> imp
                 }
             }
         } catch (URISyntaxException ex) {
-            throw new ProtocolException("Invalid URI: " +
-                    request.getRequestLine().getUri(), ex);
+            throw new ProtocolException("Invalid URI: " + request.getRequestLine().getUri(), ex);
         }
     }
 
+    private HttpRequest createConnectRequest(final HttpRoute route) {
+        // see RFC 2817, section 5.2 and
+        // INTERNET-DRAFT: Tunneling TCP based protocols through
+        // Web proxy servers
+        HttpHost target = route.getTargetHost();
+        String host = target.getHostName();
+        int port = target.getPort();
+        if (port < 0) {
+            Scheme scheme = this.connmgr.getSchemeRegistry().getScheme(target.getSchemeName());
+            port = scheme.getDefaultPort();
+        }
+        StringBuilder buffer = new StringBuilder(host.length() + 6);
+        buffer.append(host);
+        buffer.append(':');
+        buffer.append(Integer.toString(port));
+        ProtocolVersion ver = HttpProtocolParams.getVersion(this.params);
+        HttpRequest req = new BasicHttpRequest("CONNECT", buffer.toString(), ver);
+        return req;
+    }
+
 }

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -108,7 +108,7 @@ class NHttpClientProtocolHandler impleme
         }
         if (httpexchange != null) {
             HttpAsyncExchangeHandler<?> handler = httpexchange.getHandler();
-            if (handler != null && !handler.isCompleted()) {
+            if (handler != null) {
                 handler.cancel();
             }
         }
@@ -120,7 +120,7 @@ class NHttpClientProtocolHandler impleme
         this.log.error("HTTP protocol exception: " + ex.getMessage(), ex);
         if (httpexchange != null) {
             HttpAsyncExchangeHandler<?> handler = httpexchange.getHandler();
-            if (handler != null && !handler.isCompleted()) {
+            if (handler != null) {
                 handler.failed(ex);
             }
         }
@@ -133,7 +133,7 @@ class NHttpClientProtocolHandler impleme
         this.log.error("I/O error: " + ex.getMessage(), ex);
         if (httpexchange != null) {
             HttpAsyncExchangeHandler<?> handler = httpexchange.getHandler();
-            if (handler != null && !handler.isCompleted()) {
+            if (handler != null) {
                 handler.failed(ex);
             }
         }
@@ -150,7 +150,7 @@ class NHttpClientProtocolHandler impleme
         if (httpexchange.getRequestState() != MessageState.READY) {
             return;
         }
-        if (handler == null || handler.isCompleted()) {
+        if (handler == null || handler.isDone()) {
             if (this.log.isDebugEnabled()) {
                 this.log.debug("No request submitted " + formatState(conn, httpexchange));
             }
@@ -366,10 +366,12 @@ class NHttpClientProtocolHandler impleme
         if (this.log.isDebugEnabled()) {
             this.log.debug("Response processed " + formatState(conn, httpexchange));
         }
-        handler.completed();
+        handler.responseCompleted();
+        if (handler.isDone()) {
+            httpexchange.reset();
+        }
         if (conn.isOpen()) {
             // Ready for another request
-            httpexchange.reset();
             conn.requestOutput();
         }
     }

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -30,29 +30,33 @@ import java.io.IOException;
 
 import org.apache.http.HttpConnectionMetrics;
 import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.conn.ConnectionReleaseTrigger;
 import org.apache.http.conn.routing.HttpRoute;
-import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.conn.routing.RouteTracker;
+import org.apache.http.impl.conn.ConnectionShutdownException;
 import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.conn.ClientConnectionManager;
 import org.apache.http.nio.conn.ManagedClientConnection;
+import org.apache.http.nio.conn.OperatedClientConnection;
+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.protocol.HttpContext;
 
-class ClientConnAdaptor implements ManagedClientConnection, ConnectionReleaseTrigger {
+class ClientConnAdaptor implements ManagedClientConnection {
 
     private final ClientConnectionManager manager;
     private volatile HttpPoolEntry entry;
-    private volatile NHttpClientConnection conn;
+    private volatile OperatedClientConnection conn;
     private volatile boolean released;
     private volatile boolean reusable;
 
     public ClientConnAdaptor(
             final ClientConnectionManager manager,
             final HttpPoolEntry entry,
-            final NHttpClientConnection conn) {
+            final OperatedClientConnection conn) {
         super();
         this.manager = manager;
         this.entry = entry;
@@ -142,10 +146,15 @@ class ClientConnAdaptor implements Manag
 
     private void assertValid() {
         if (this.released) {
-            throw new IllegalStateException("I/O session has been released");
+            throw new ConnectionShutdownException();
         }
     }
 
+    public HttpRoute getRoute() {
+        assertValid();
+        return this.entry.getEffectiveRoute();
+    }
+
     public synchronized HttpConnectionMetrics getMetrics() {
         assertValid();
         return this.conn.getMetrics();
@@ -221,9 +230,79 @@ class ClientConnAdaptor implements Manag
         this.conn.submitRequest(request);
     }
 
+    public synchronized void updateOpen(final HttpRoute route) {
+        assertValid();
+        RouteTracker tracker = this.entry.getTracker();
+        if (tracker.isConnected()) {
+            throw new IllegalStateException("Connection already open");
+        }
+        HttpHost target = route.getTargetHost();
+        HttpHost proxy = route.getProxyHost();
+        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);
+            }
+        } else {
+            tracker.connectProxy(proxy, false);
+        }
+    }
+
+    public synchronized void updateTunnelProxy(final HttpHost next){
+        assertValid();
+        RouteTracker tracker = this.entry.getTracker();
+        if (!tracker.isConnected()) {
+            throw new IllegalStateException("Connection not open");
+        }
+        tracker.tunnelProxy(next, false);
+    }
+
+    public synchronized void updateTunnelTarget() {
+        assertValid();
+        RouteTracker tracker = this.entry.getTracker();
+        if (!tracker.isConnected()) {
+            throw new IllegalStateException("Connection not open");
+        }
+        if (tracker.isTunnelled()) {
+            throw new IllegalStateException("Connection is already tunnelled");
+        }
+        tracker.tunnelTarget(false);
+    }
+
+    public synchronized void updateLayered(){
+        assertValid();
+        RouteTracker tracker = this.entry.getTracker();
+        if (!tracker.isConnected()) {
+            throw new IllegalStateException("Connection not open");
+        }
+        if (!tracker.isTunnelled()) {
+            throw new IllegalStateException("Protocol layering without a tunnel not supported");
+        }
+        if (tracker.isLayered()) {
+            throw new IllegalStateException("Multiple protocol layering not supported");
+        }
+        HttpHost target = tracker.getTargetHost();
+        Scheme scheme = this.manager.getSchemeRegistry().getScheme(target);
+        LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
+        if (layeringStrategy == null) {
+            throw new IllegalStateException(scheme.getName() +
+                    " scheme does not provider support for protocol layering");
+        }
+        IOSession iosession = this.entry.getIOSession();
+        iosession = layeringStrategy.layer(iosession);
+        this.conn.upgrade(iosession);
+        tracker.layerProtocol(layeringStrategy.isSecure());
+    }
+
     @Override
-    public String toString() {
-        HttpRoute route = this.entry.getRoute();
+    public synchronized String toString() {
+        HttpRoute route = this.entry.getPlannedRoute();
         StringBuilder buffer = new StringBuilder();
         buffer.append("HTTP connection: ");
         if (route.getLocalAddress() != null) {

Added: 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=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,151 @@
+/*
+ * ====================================================================
+ * 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 java.io.IOException;
+import java.nio.channels.ReadableByteChannel;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.Header;
+import org.apache.http.HttpException;
+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.nio.NHttpMessageParser;
+import org.apache.http.nio.NHttpMessageWriter;
+import org.apache.http.nio.conn.OperatedClientConnection;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionInputBuffer;
+import org.apache.http.nio.reactor.SessionOutputBuffer;
+import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.params.HttpParams;
+
+public class DefaultClientConnection
+                        extends DefaultNHttpClientConnection implements OperatedClientConnection {
+
+    private final Log headerlog = LogFactory.getLog("org.apache.http.headers");
+    private final Log wirelog   = LogFactory.getLog("org.apache.http.wire");
+    private final Log log;
+
+    public DefaultClientConnection(
+            final IOSession iosession,
+            final HttpResponseFactory responseFactory,
+            final ByteBufferAllocator allocator,
+            final HttpParams params) {
+        super(iosession, responseFactory, allocator, params);
+        this.log = LogFactory.getLog(iosession.getClass());
+        upgrade(iosession);
+    }
+
+    public void upgrade(final IOSession iosession) {
+        if (this.log.isDebugEnabled() || this.wirelog.isDebugEnabled()) {
+            this.session = new LoggingIOSession(
+                    iosession, this.headerlog, this.wirelog);
+        } else {
+            this.session = iosession;
+        }
+    }
+
+    @Override
+    protected NHttpMessageWriter<HttpRequest> createRequestWriter(
+            final SessionOutputBuffer buffer,
+            final HttpParams params) {
+        return new LoggingNHttpMessageWriter(
+                super.createRequestWriter(buffer, params));
+    }
+
+    @Override
+    protected NHttpMessageParser<HttpResponse> createResponseParser(
+            final SessionInputBuffer buffer,
+            final HttpResponseFactory responseFactory,
+            final HttpParams params) {
+        return new LoggingNHttpMessageParser(
+                super.createResponseParser(buffer, responseFactory, params));
+    }
+
+    class LoggingNHttpMessageWriter implements NHttpMessageWriter<HttpRequest> {
+
+        private final NHttpMessageWriter<HttpRequest> writer;
+
+        public LoggingNHttpMessageWriter(final NHttpMessageWriter<HttpRequest> writer) {
+            super();
+            this.writer = writer;
+        }
+
+        public void reset() {
+            this.writer.reset();
+        }
+
+        public void write(final HttpRequest request) throws IOException, HttpException {
+            if (request != null && headerlog.isDebugEnabled()) {
+                headerlog.debug(">> " + request.getRequestLine().toString());
+                Header[] headers = request.getAllHeaders();
+                for (int i = 0; i < headers.length; i++) {
+                    headerlog.debug(">> " + headers[i].toString());
+                }
+            }
+            this.writer.write(request);
+        }
+
+    }
+
+    class LoggingNHttpMessageParser implements NHttpMessageParser<HttpResponse> {
+
+        private final NHttpMessageParser<HttpResponse> parser;
+
+        public LoggingNHttpMessageParser(final NHttpMessageParser<HttpResponse> parser) {
+            super();
+            this.parser = parser;
+        }
+
+        public void reset() {
+            this.parser.reset();
+        }
+
+        public int fillBuffer(final ReadableByteChannel channel) throws IOException {
+            return this.parser.fillBuffer(channel);
+        }
+
+        public HttpResponse parse() throws IOException, HttpException {
+            HttpResponse response = this.parser.parse();
+            if (headerlog.isDebugEnabled()) {
+                if (response != null && headerlog.isDebugEnabled()) {
+                    headerlog.debug("<< " + response.getStatusLine().toString());
+                    Header[] headers = response.getAllHeaders();
+                    for (int i = 0; i < headers.length; i++) {
+                        headerlog.debug("<< " + headers[i].toString());
+                    }
+                }
+            }
+            return response;
+        }
+
+    }
+
+}

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultClientConnection.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultHttpAsyncRoutePlanner.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultHttpAsyncRoutePlanner.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultHttpAsyncRoutePlanner.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/DefaultHttpAsyncRoutePlanner.java Thu Dec 16 20:49:14 2010
@@ -32,6 +32,9 @@ import java.net.InetAddress;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
+import org.apache.http.nio.conn.scheme.LayeringStrategy;
+import org.apache.http.nio.conn.scheme.Scheme;
+import org.apache.http.nio.conn.scheme.SchemeRegistry;
 import org.apache.http.protocol.HttpContext;
 
 import org.apache.http.conn.routing.HttpRoute;
@@ -41,8 +44,11 @@ import org.apache.http.conn.params.ConnR
 
 public class DefaultHttpAsyncRoutePlanner implements HttpRoutePlanner {
 
-    public DefaultHttpAsyncRoutePlanner() {
+    private final SchemeRegistry schemeRegistry;
+
+    public DefaultHttpAsyncRoutePlanner(final SchemeRegistry schemeRegistry) {
         super();
+        this.schemeRegistry = schemeRegistry;
     }
 
     public HttpRoute determineRoute(
@@ -59,10 +65,11 @@ public class DefaultHttpAsyncRoutePlanne
         if (target == null) {
             throw new IllegalStateException("Target host may be null");
         }
-
         InetAddress local = ConnRouteParams.getLocalAddress(request.getParams());
         HttpHost proxy = ConnRouteParams.getDefaultProxy(request.getParams());
-        boolean secure = target.getSchemeName().equalsIgnoreCase("https");
+        Scheme scheme = this.schemeRegistry.getScheme(target);
+        LayeringStrategy layeringStrategy = scheme.getLayeringStrategy();
+        boolean secure = layeringStrategy != null && layeringStrategy.isSecure();
         if (proxy == null) {
             route = new HttpRoute(target, local, secure);
         } else {

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpPoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpPoolEntry.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpPoolEntry.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/HttpPoolEntry.java Thu Dec 16 20:49:14 2010
@@ -40,8 +40,31 @@ public class HttpPoolEntry extends PoolE
         this.tracker = new RouteTracker(route);
     }
 
+    @Override
+    public IOSession getIOSession() {
+        return super.getIOSession();
+    }
+
+    public HttpRoute getPlannedRoute() {
+        return super.getRoute();
+    }
+
+    @Override
+    public Object getState() {
+        return super.getState();
+    }
+
+    @Override
+    public void setState(final Object state) {
+        super.setState(state);
+    }
+
     protected RouteTracker getTracker() {
-        return tracker;
+        return this.tracker;
+    }
+
+    public HttpRoute getEffectiveRoute() {
+        return this.tracker.toRoute();
     }
 
 }

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -34,24 +34,43 @@ import org.apache.http.conn.routing.Http
 import org.apache.http.impl.nio.pool.PoolEntryFactory;
 import org.apache.http.impl.nio.pool.RouteResolver;
 import org.apache.http.impl.nio.pool.SessionPool;
+import org.apache.http.nio.conn.scheme.Scheme;
+import org.apache.http.nio.conn.scheme.SchemeRegistry;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOSession;
 
 class HttpSessionPool extends SessionPool<HttpRoute, HttpPoolEntry> {
 
-    public HttpSessionPool(final ConnectingIOReactor ioreactor) {
-        super(ioreactor, new InternalEntryFactory(), new InternalRouteResolver(), 20, 50);
+    public HttpSessionPool(
+            final ConnectingIOReactor ioreactor, final SchemeRegistry schemeRegistry) {
+        super(ioreactor,
+                new InternalEntryFactory(),
+                new InternalRouteResolver(schemeRegistry),
+                20, 50);
     }
 
     static class InternalRouteResolver implements RouteResolver<HttpRoute> {
 
+        private final SchemeRegistry schemeRegistry;
+
+        InternalRouteResolver(final SchemeRegistry schemeRegistry) {
+            super();
+            this.schemeRegistry = schemeRegistry;
+        }
+
         public SocketAddress resolveLocalAddress(final HttpRoute route) {
             return new InetSocketAddress(route.getLocalAddress(), 0);
         }
 
         public SocketAddress resolveRemoteAddress(final HttpRoute route) {
             HttpHost target = route.getTargetHost();
-            return new InetSocketAddress(target.getHostName(), target.getPort());
+            String hostname = target.getHostName();
+            int port = target.getPort();
+            if (port < 0) {
+                Scheme scheme = this.schemeRegistry.getScheme(target);
+                port = scheme.resolvePort(port);
+            }
+            return new InetSocketAddress(hostname, port);
         }
 
     }

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/LoggingIOSession.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/LoggingIOSession.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/LoggingIOSession.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/conn/LoggingIOSession.java Thu Dec 16 20:49:14 2010
@@ -38,7 +38,7 @@ import org.apache.commons.logging.Log;
 import org.apache.http.nio.reactor.IOSession;
 import org.apache.http.nio.reactor.SessionBufferStatus;
 
-public class LoggingIOSession implements IOSession {
+class LoggingIOSession implements IOSession {
 
     private static AtomicLong COUNT = new AtomicLong(0);
 

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -34,14 +34,14 @@ import org.apache.commons.logging.LogFac
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.conn.routing.HttpRoute;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.nio.DefaultNHttpClientConnection;
 import org.apache.http.impl.nio.pool.PoolEntryCallback;
-import org.apache.http.nio.NHttpClientConnection;
 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;
@@ -51,15 +51,16 @@ import org.apache.http.protocol.Executio
 
 public class PoolingClientConnectionManager implements ClientConnectionManager {
 
-    private static final String HEADERS    = "org.apache.http.headers";
-    private static final String WIRE       = "org.apache.http.wire";
-
     private final Log log = LogFactory.getLog(getClass());
 
     private final HttpSessionPool pool;
+    private final SchemeRegistry schemeRegistry;
     private final HttpParams params;
 
-    public PoolingClientConnectionManager(final ConnectingIOReactor ioreactor, final HttpParams params) {
+    public PoolingClientConnectionManager(
+            final ConnectingIOReactor ioreactor,
+            final SchemeRegistry schemeRegistry,
+            final HttpParams params) {
         super();
         if (ioreactor == null) {
             throw new IllegalArgumentException("I/O reactor may not be null");
@@ -67,14 +68,19 @@ public class PoolingClientConnectionMana
         if (params == null) {
             throw new IllegalArgumentException("HTTP parameters may not be null");
         }
-        this.pool = new HttpSessionPool(ioreactor);
+        this.pool = new HttpSessionPool(ioreactor, schemeRegistry);
+        this.schemeRegistry = schemeRegistry;
         this.params = params;
     }
 
+    public SchemeRegistry getSchemeRegistry() {
+        return this.schemeRegistry;
+    }
+
     public synchronized Future<ManagedClientConnection> leaseConnection(
             final HttpRoute route,
             final Object state,
-            final long connectTimeout,
+            final long timeout,
             final TimeUnit timeUnit,
             final FutureCallback<ManagedClientConnection> callback) {
         if (this.log.isDebugEnabled()) {
@@ -86,7 +92,7 @@ public class PoolingClientConnectionMana
         }
         BasicFuture<ManagedClientConnection> future = new BasicFuture<ManagedClientConnection>(
                 callback);
-        this.pool.lease(route, state, connectTimeout, timeUnit, new InternalPoolEntryCallback(future));
+        this.pool.lease(route, state, timeout, timeUnit, new InternalPoolEntryCallback(future));
         if (this.log.isDebugEnabled()) {
             if (!future.isDone()) {
                 this.log.debug("I/O session could not be allocated immediately: " +
@@ -111,7 +117,7 @@ public class PoolingClientConnectionMana
         HttpPoolEntry entry = adaptor.getEntry();
         IOSession iosession = entry.getIOSession();
         if (this.log.isDebugEnabled()) {
-            HttpRoute route = entry.getRoute();
+            HttpRoute route = entry.getPlannedRoute();
             PoolStats totals = this.pool.getTotalStats();
             PoolStats stats = this.pool.getStats(route);
             this.log.debug("Total: " + totals);
@@ -168,31 +174,16 @@ public class PoolingClientConnectionMana
             if (log.isDebugEnabled()) {
                 log.debug("I/O session allocated: " + entry);
             }
-            IOSession session = entry.getIOSession();
-            NHttpClientConnection conn = (NHttpClientConnection) session.getAttribute(
+            IOSession iosession = entry.getIOSession();
+            OperatedClientConnection conn = (OperatedClientConnection) iosession.getAttribute(
                     ExecutionContext.HTTP_CONNECTION);
             if (conn == null) {
-                Log log = LogFactory.getLog(session.getClass());
-                Log wirelog = LogFactory.getLog(WIRE);
-                Log headerlog = LogFactory.getLog(HEADERS);
-                if (log.isDebugEnabled() || wirelog.isDebugEnabled()) {
-                    session = new LoggingIOSession(session, log, wirelog);
-                }
-                if (headerlog.isDebugEnabled()) {
-                    conn = new LoggingNHttpClientConnection(
-                            headerlog,
-                            session,
-                            createHttpResponseFactory(),
-                            createByteBufferAllocator(),
-                            params);
-                } else {
-                    conn = new DefaultNHttpClientConnection(
-                            session,
-                            createHttpResponseFactory(),
-                            createByteBufferAllocator(),
-                            params);
-                }
-                session.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
+                conn = new DefaultClientConnection(
+                        iosession,
+                        createHttpResponseFactory(),
+                        createByteBufferAllocator(),
+                        params);
+                iosession.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
             }
             ClientConnAdaptor result = new ClientConnAdaptor(
                     PoolingClientConnectionManager.this,

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/pool/PoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/pool/PoolEntry.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/pool/PoolEntry.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/impl/nio/pool/PoolEntry.java Thu Dec 16 20:49:14 2010
@@ -46,18 +46,19 @@ public abstract class PoolEntry<T> {
         this.id = COUNTER.incrementAndGet();
     }
 
-    public T getRoute() {
+    protected T getRoute() {
         return this.route;
     }
 
-    public IOSession getIOSession() {
+    protected IOSession getIOSession() {
         return this.session;
     }
-    public Object getState() {
+
+    protected Object getState() {
         return this.state;
     }
 
-    public void setState(final Object state) {
+    protected void setState(final Object state) {
         this.state = state;
     }
 

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncResponseConsumer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncResponseConsumer.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncResponseConsumer.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/client/HttpAsyncResponseConsumer.java Thu Dec 16 20:49:14 2010
@@ -39,13 +39,13 @@ public interface HttpAsyncResponseConsum
 
     void consumeContent(ContentDecoder decoder, IOControl ioctrl) throws IOException;
 
-    void completed();
+    void responseCompleted();
 
     void failed(Exception ex);
 
     void cancel();
 
-    boolean isCompleted();
+    boolean isDone();
 
     T getResult();
 

Modified: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ClientConnectionManager.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ClientConnectionManager.java?rev=1050153&r1=1050152&r2=1050153&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ClientConnectionManager.java (original)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ClientConnectionManager.java Thu Dec 16 20:49:14 2010
@@ -31,9 +31,12 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.http.conn.routing.HttpRoute;
 import org.apache.http.nio.concurrent.FutureCallback;
+import org.apache.http.nio.conn.scheme.SchemeRegistry;
 
 public interface ClientConnectionManager {
 
+    SchemeRegistry getSchemeRegistry();
+
     Future<ManagedClientConnection> leaseConnection(
             HttpRoute route, Object state,
             long connectTimeout, TimeUnit timeUnit,

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=1050153&r1=1050152&r2=1050153&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 Thu Dec 16 20:49:14 2010
@@ -26,10 +26,15 @@
  */
 package org.apache.http.nio.conn;
 
+import org.apache.http.HttpHost;
+import org.apache.http.conn.ConnectionReleaseTrigger;
+import org.apache.http.conn.routing.HttpRoute;
 import org.apache.http.nio.NHttpClientConnection;
 
-public interface ManagedClientConnection extends NHttpClientConnection {
+public interface ManagedClientConnection extends NHttpClientConnection, ConnectionReleaseTrigger {
 
+    HttpRoute getRoute();
+    
     Object getState();
 
     void setState(Object state);
@@ -39,9 +44,13 @@ public interface ManagedClientConnection
     void markNonReusable();
 
     boolean isReusable();
-
-    void releaseConnection();
-
-    void abortConnection();
-
+    
+    void updateOpen(HttpRoute route);
+    
+    void updateTunnelTarget();
+    
+    void updateTunnelProxy(HttpHost next);
+    
+    void updateLayered();
+    
 }

Added: 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=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,36 @@
+/*
+ * ====================================================================
+ * 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.nio.conn;
+
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.reactor.IOSession;
+
+public interface OperatedClientConnection extends NHttpClientConnection {
+
+    void upgrade(IOSession iosession);
+
+}

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/OperatedClientConnection.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java?rev=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,37 @@
+/*
+ * ====================================================================
+ * 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.nio.conn.scheme;
+
+import org.apache.http.nio.reactor.IOSession;
+
+public interface LayeringStrategy {
+
+    boolean isSecure();
+
+    IOSession layer(IOSession iosession);
+
+}

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/LayeringStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java?rev=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,114 @@
+/*
+ * ====================================================================
+ * 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.nio.conn.scheme;
+
+import java.util.Locale;
+
+import org.apache.http.util.LangUtils;
+
+public final class Scheme {
+
+    /** The name of this scheme, in lowercase. (e.g. http, https) */
+    private final String name;
+
+    /** The layering strategy for this scheme, if applicable */
+    private final LayeringStrategy strategy;
+
+    /** The default port for this scheme */
+    private final int defaultPort;
+
+    /** A string representation, for {@link #toString toString}. */
+    private String stringRep;
+    /*
+     *  This is used to cache the result of the toString() method
+     *  Since the method always generates the same value, there's no
+     *  need to synchronize, and it does not affect immutability.
+    */
+
+    public Scheme(final String name, final int port, final LayeringStrategy strategy) {
+        if (name == null) {
+            throw new IllegalArgumentException("Scheme name may not be null");
+        }
+        if ((port <= 0) || (port > 0xffff)) {
+            throw new IllegalArgumentException("Port is invalid: " + port);
+        }
+        this.name = name.toLowerCase(Locale.ENGLISH);
+        this.strategy = strategy;
+        this.defaultPort = port;
+    }
+
+    public final int getDefaultPort() {
+        return defaultPort;
+    }
+
+    public final LayeringStrategy getLayeringStrategy() {
+        return this.strategy;
+    }
+
+    public final String getName() {
+        return name;
+    }
+
+    public final int resolvePort(int port) {
+        return port <= 0 ? defaultPort : port;
+    }
+
+    @Override
+    public final String toString() {
+        if (stringRep == null) {
+            StringBuilder buffer = new StringBuilder();
+            buffer.append(this.name);
+            buffer.append(':');
+            buffer.append(Integer.toString(this.defaultPort));
+            stringRep = buffer.toString();
+        }
+        return stringRep;
+    }
+
+    @Override
+    public final boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj instanceof Scheme) {
+            Scheme that = (Scheme) obj;
+            return this.name.equals(that.name)
+                && this.defaultPort == that.defaultPort
+                && this.strategy.equals(that.strategy);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = LangUtils.HASH_SEED;
+        hash = LangUtils.hashCode(hash, this.defaultPort);
+        hash = LangUtils.hashCode(hash, this.name);
+        hash = LangUtils.hashCode(hash, this.strategy);
+        return hash;
+    }
+
+}

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/Scheme.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java?rev=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,169 @@
+/*
+ * ====================================================================
+ * 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.nio.conn.scheme;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.http.HttpHost;
+
+/**
+ * A set of supported protocol {@link Scheme}s.
+ * Schemes are identified by lowercase names.
+ *
+ */
+public final class SchemeRegistry {
+
+    /** The available schemes in this registry. */
+    private final Map<String, Scheme> registeredSchemes;
+
+    /**
+     * Creates a new, empty scheme registry.
+     */
+    public SchemeRegistry() {
+        super();
+        registeredSchemes = new ConcurrentHashMap<String, Scheme>();
+    }
+
+    /**
+     * Obtains a scheme by name.
+     *
+     * @param name      the name of the scheme to look up (in lowercase)
+     *
+     * @return  the scheme, never <code>null</code>
+     *
+     * @throws IllegalStateException
+     *          if the scheme with the given name is not registered
+     */
+    public final Scheme getScheme(String name) {
+        Scheme found = get(name);
+        if (found == null) {
+            throw new IllegalStateException
+                ("Scheme '"+name+"' not registered.");
+        }
+        return found;
+    }
+
+    /**
+     * Obtains the scheme for a host.
+     * Convenience method for <code>getScheme(host.getSchemeName())</pre>
+     *
+     * @param host      the host for which to obtain the scheme
+     *
+     * @return  the scheme for the given host, never <code>null</code>
+     *
+     * @throws IllegalStateException
+     *          if a scheme with the respective name is not registered
+     */
+    public final Scheme getScheme(HttpHost host) {
+        if (host == null) {
+            throw new IllegalArgumentException("Host must not be null.");
+        }
+        return getScheme(host.getSchemeName());
+    }
+
+    /**
+     * Obtains a scheme by name, if registered.
+     *
+     * @param name      the name of the scheme to look up (in lowercase)
+     *
+     * @return  the scheme, or
+     *          <code>null</code> if there is none by this name
+     */
+    public final Scheme get(String name) {
+        if (name == null)
+            throw new IllegalArgumentException("Name must not be null.");
+
+        // leave it to the caller to use the correct name - all lowercase
+        //name = name.toLowerCase();
+        Scheme found = registeredSchemes.get(name);
+        return found;
+    }
+
+    /**
+     * Registers a scheme.
+     * The scheme can later be retrieved by its name
+     * using {@link #getScheme(String) getScheme} or {@link #get get}.
+     *
+     * @param sch       the scheme to register
+     *
+     * @return  the scheme previously registered with that name, or
+     *          <code>null</code> if none was registered
+     */
+    public final Scheme register(Scheme sch) {
+        if (sch == null)
+            throw new IllegalArgumentException("Scheme must not be null.");
+
+        Scheme old = registeredSchemes.put(sch.getName(), sch);
+        return old;
+    }
+
+    /**
+     * Unregisters a scheme.
+     *
+     * @param name      the name of the scheme to unregister (in lowercase)
+     *
+     * @return  the unregistered scheme, or
+     *          <code>null</code> if there was none
+     */
+    public final Scheme unregister(String name) {
+        if (name == null)
+            throw new IllegalArgumentException("Name must not be null.");
+
+        // leave it to the caller to use the correct name - all lowercase
+        //name = name.toLowerCase();
+        Scheme gone = registeredSchemes.remove(name);
+        return gone;
+    }
+
+    /**
+     * Obtains the names of the registered schemes.
+     *
+     * @return  List containing registered scheme names.
+     */
+    public final List<String> getSchemeNames() {
+        return new ArrayList<String>(registeredSchemes.keySet());
+    }
+
+    /**
+     * Populates the internal collection of registered {@link Scheme protocol schemes}
+     * with the content of the map passed as a parameter.
+     *
+     * @param map protocol schemes
+     */
+    public void setItems(final Map<String, Scheme> map) {
+        if (map == null) {
+            return;
+        }
+        registeredSchemes.clear();
+        registeredSchemes.putAll(map);
+    }
+
+}
+

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/scheme/SchemeRegistry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 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=1050153&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java (added)
+++ httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java Thu Dec 16 20:49:14 2010
@@ -0,0 +1,196 @@
+/*
+ * ====================================================================
+ * 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.nio.conn.ssl;
+
+import java.net.InetSocketAddress;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.impl.nio.reactor.SSLIOSession;
+import org.apache.http.impl.nio.reactor.SSLSetupHandler;
+import org.apache.http.nio.conn.scheme.LayeringStrategy;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.params.HttpParams;
+
+public class SSLLayeringStrategy implements LayeringStrategy {
+
+    public static final String TLS   = "TLS";
+    public static final String SSL   = "SSL";
+    public static final String SSLV2 = "SSLv2";
+
+    private final SSLContext sslContext;
+    private final X509HostnameVerifier hostnameVerifier;
+
+    private static SSLContext createSSLContext(
+            final String algorithm,
+            final KeyStore keystore,
+            final String keystorePassword,
+            final KeyStore truststore,
+            final SecureRandom random,
+            final TrustStrategy trustStrategy)
+                throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
+        String algo = algorithm != null ? algorithm : TLS;
+        KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
+                KeyManagerFactory.getDefaultAlgorithm());
+        kmfactory.init(keystore, keystorePassword != null ? keystorePassword.toCharArray(): null);
+        KeyManager[] keymanagers =  kmfactory.getKeyManagers();
+        TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
+                TrustManagerFactory.getDefaultAlgorithm());
+        tmfactory.init(truststore);
+        TrustManager[] trustmanagers = tmfactory.getTrustManagers();
+        if (trustmanagers != null && trustStrategy != null) {
+            for (int i = 0; i < trustmanagers.length; i++) {
+                TrustManager tm = trustmanagers[i];
+                if (tm instanceof X509TrustManager) {
+                    trustmanagers[i] = new TrustManagerDecorator(
+                            (X509TrustManager) tm, trustStrategy);
+                }
+            }
+        }
+        SSLContext sslcontext = SSLContext.getInstance(algo);
+        sslcontext.init(keymanagers, trustmanagers, random);
+        return sslcontext;
+    }
+
+    public SSLLayeringStrategy(
+            final String algorithm,
+            final KeyStore keystore,
+            final String keystorePassword,
+            final KeyStore truststore,
+            final SecureRandom random,
+            final X509HostnameVerifier hostnameVerifier)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(createSSLContext(
+                algorithm, keystore, keystorePassword, truststore, random, null),
+                hostnameVerifier);
+    }
+
+    public SSLLayeringStrategy(
+            final String algorithm,
+            final KeyStore keystore,
+            final String keystorePassword,
+            final KeyStore truststore,
+            final SecureRandom random,
+            final TrustStrategy trustStrategy,
+            final X509HostnameVerifier hostnameVerifier)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(createSSLContext(
+                algorithm, keystore, keystorePassword, truststore, random, trustStrategy),
+                hostnameVerifier);
+    }
+
+    public SSLLayeringStrategy(
+            final KeyStore keystore,
+            final String keystorePassword,
+            final KeyStore truststore)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(TLS, keystore, keystorePassword, truststore, null, null, new BrowserCompatHostnameVerifier());
+    }
+
+    public SSLLayeringStrategy(
+            final KeyStore keystore,
+            final String keystorePassword)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
+        this(TLS, keystore, keystorePassword, null, null, null, new BrowserCompatHostnameVerifier());
+    }
+
+    public SSLLayeringStrategy(
+            final KeyStore truststore)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(TLS, null, null, truststore, null, null, new BrowserCompatHostnameVerifier());
+    }
+
+    public SSLLayeringStrategy(
+            final TrustStrategy trustStrategy,
+            final X509HostnameVerifier hostnameVerifier)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(TLS, null, null, null, null, trustStrategy, hostnameVerifier);
+    }
+
+    public SSLLayeringStrategy(
+            final TrustStrategy trustStrategy)
+                throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+        this(TLS, null, null, null, null, trustStrategy, new BrowserCompatHostnameVerifier());
+    }
+
+    public SSLLayeringStrategy(
+            final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
+        super();
+        this.sslContext = sslContext;
+        this.hostnameVerifier = hostnameVerifier;
+    }
+
+    public SSLLayeringStrategy(final SSLContext sslContext) {
+        this(sslContext, new BrowserCompatHostnameVerifier());
+    }
+
+    public boolean isSecure() {
+        return true;
+    }
+
+    public IOSession layer(final IOSession iosession) {
+        return new SSLIOSession(iosession, this.sslContext, new InternalSSLSetupHandler());
+    }
+
+    protected void initializeEngine(final SSLEngine engine) {
+    }
+
+    class InternalSSLSetupHandler implements SSLSetupHandler {
+
+        public void initalize(
+                final SSLEngine sslengine,
+                final HttpParams params) throws SSLException {
+            initializeEngine(sslengine);
+        }
+
+        public void verify(
+                final IOSession iosession,
+                final SSLSession sslsession) throws SSLException {
+            InetSocketAddress address = (InetSocketAddress) iosession.getRemoteAddress();
+            hostnameVerifier.verify(address.getHostName(), sslsession);
+        }
+
+    }
+}

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpasyncclient/trunk/src/main/java/org/apache/http/nio/conn/ssl/SSLLayeringStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message