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 2017/09/01 18:15:25 UTC

[1/6] httpcomponents-client git commit: Upgraded HttpCore to version 5.0-alpha4

Repository: httpcomponents-client
Updated Branches:
  refs/heads/master 272ea1fa8 -> e8f72b7c5


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestFutureRequestExecutionService.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestFutureRequestExecutionService.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestFutureRequestExecutionService.java
index 689eac5..24cdffe 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestFutureRequestExecutionService.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestFutureRequestExecutionService.java
@@ -49,8 +49,8 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.ResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.After;
 import org.junit.Assert;
@@ -69,7 +69,7 @@ public class TestFutureRequestExecutionService {
     @Before
     public void before() throws Exception {
         this.localServer = ServerBootstrap.bootstrap()
-                .registerHandler("/wait", new HttpRequestHandler() {
+                .register("/wait", new HttpRequestHandler() {
 
             @Override
             public void handle(
@@ -190,7 +190,7 @@ public class TestFutureRequestExecutionService {
     }
 
 
-    private final class OkidokiHandler implements ResponseHandler<Boolean> {
+    private final class OkidokiHandler implements HttpClientResponseHandler<Boolean> {
         @Override
         public Boolean handleResponse(
                 final ClassicHttpResponse response) throws IOException {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bc84e16..1726f3a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,7 +68,7 @@
   <properties>
     <maven.compiler.source>1.7</maven.compiler.source>
     <maven.compiler.target>1.7</maven.compiler.target>
-    <httpcore.version>5.0-alpha3</httpcore.version>
+    <httpcore.version>5.0-alpha4</httpcore.version>
     <log4j.version>2.8.2</log4j.version>
     <commons-codec.version>1.10</commons-codec.version>
     <ehcache.version>2.6.11</ehcache.version>


[2/6] httpcomponents-client git commit: Upgraded HttpCore to version 5.0-alpha4

Posted by ol...@apache.org.
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
index f227096..f4ce0a6 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
@@ -44,12 +44,15 @@ import org.apache.hc.core5.concurrent.Cancellable;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.function.Callback;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncRequestProducer;
 import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
+import org.apache.hc.core5.http.nio.RequestChannel;
 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
@@ -57,11 +60,11 @@ import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOReactorException;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
 
@@ -75,11 +78,13 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
             final IOReactorConfig reactorConfig,
             final ThreadFactory threadFactory,
             final ThreadFactory workerThreadFactory,
-            final AsyncClientConnectionManager connmgr) throws IOReactorException {
+            final AsyncClientConnectionManager connmgr) {
         super(new DefaultConnectingIOReactor(
                 eventHandlerFactory,
                 reactorConfig,
                 workerThreadFactory,
+                null,
+                null,
                 new Callback<IOSession>() {
 
                     @Override
@@ -96,7 +101,7 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
 
     private Future<AsyncConnectionEndpoint> leaseEndpoint(
             final HttpHost host,
-            final TimeValue connectTimeout,
+            final Timeout connectTimeout,
             final HttpClientContext clientContext,
             final FutureCallback<AsyncConnectionEndpoint> callback) {
         final ComplexFuture<AsyncConnectionEndpoint> resultFuture = new ComplexFuture<>(callback);
@@ -197,8 +202,6 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
             final HttpContext context,
             final FutureCallback<T> callback) {
         ensureRunning();
-        final HttpRequest request = requestProducer.produceRequest();
-        final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
         final HttpClientContext clientContext = HttpClientContext.adapt(context);
         RequestConfig requestConfig = null;
         if (requestProducer instanceof Configurable) {
@@ -210,58 +213,73 @@ public class MinimalHttpAsyncClient extends AbstractHttpAsyncClientBase {
             requestConfig = clientContext.getRequestConfig();
         }
         final ComplexFuture<T> resultFuture = new ComplexFuture<>(callback);
-        final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(target, requestConfig.getConnectTimeout(), clientContext,
-                new FutureCallback<AsyncConnectionEndpoint>() {
+        try {
+            final Timeout connectTimeout = requestConfig.getConnectTimeout();
+            requestProducer.sendRequest(new RequestChannel() {
 
-                    @Override
-                    public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
-                        final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
-                        endpoint.execute(requestProducer, responseConsumer, clientContext, new FutureCallback<T>() {
-
-                            @Override
-                            public void completed(final T result) {
-                                endpoint.releaseAndReuse();
-                                resultFuture.completed(result);
-                            }
-
-                            @Override
-                            public void failed(final Exception ex) {
-                                endpoint.releaseAndDiscard();
-                                resultFuture.failed(ex);
-                            }
-
-                            @Override
-                            public void cancelled() {
-                                endpoint.releaseAndDiscard();
-                                resultFuture.cancel();
-                            }
-
-                        });
-                        resultFuture.setDependency(new Cancellable() {
-
-                            @Override
-                            public boolean cancel() {
-                                final boolean active = !endpoint.isReleased();
-                                endpoint.releaseAndDiscard();
-                                return active;
-                            }
-
-                        });
+                @Override
+                public void sendRequest(
+                        final HttpRequest request,
+                        final EntityDetails entityDetails) throws HttpException, IOException {
+                    final HttpHost target = new HttpHost(request.getAuthority(), request.getScheme());
+                    final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(target, connectTimeout, clientContext,
+                            new FutureCallback<AsyncConnectionEndpoint>() {
+
+                                @Override
+                                public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
+                                    final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
+                                    endpoint.execute(requestProducer, responseConsumer, clientContext, new FutureCallback<T>() {
 
-                    }
+                                        @Override
+                                        public void completed(final T result) {
+                                            endpoint.releaseAndReuse();
+                                            resultFuture.completed(result);
+                                        }
 
-                    @Override
-                    public void failed(final Exception ex) {
-                        resultFuture.failed(ex);
-                    }
+                                        @Override
+                                        public void failed(final Exception ex) {
+                                            endpoint.releaseAndDiscard();
+                                            resultFuture.failed(ex);
+                                        }
 
-                    @Override
-                    public void cancelled() {
-                        resultFuture.cancel();
-                    }
+                                        @Override
+                                        public void cancelled() {
+                                            endpoint.releaseAndDiscard();
+                                            resultFuture.cancel();
+                                        }
 
-                });
-        resultFuture.setDependency(leaseFuture);
+                                    });
+                                    resultFuture.setDependency(new Cancellable() {
+
+                                        @Override
+                                        public boolean cancel() {
+                                            final boolean active = !endpoint.isReleased();
+                                            endpoint.releaseAndDiscard();
+                                            return active;
+                                        }
+
+                                    });
+
+                                }
+
+                                @Override
+                                public void failed(final Exception ex) {
+                                    resultFuture.failed(ex);
+                                }
+
+                                @Override
+                                public void cancelled() {
+                                    resultFuture.cancel();
+                                }
+
+                            });
+                    resultFuture.setDependency(leaseFuture);
+                }
+            });
+
+        } catch (final HttpException | IOException ex) {
+            resultFuture.failed(ex);
+        }
         return resultFuture;
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
index 429677a..4dca6a7 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
@@ -65,8 +65,8 @@ import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.pool.ConnPoolControl;
 import org.apache.hc.core5.pool.ConnPoolListener;
-import org.apache.hc.core5.pool.ConnPoolPolicy;
 import org.apache.hc.core5.pool.PoolEntry;
+import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.pool.PoolStats;
 import org.apache.hc.core5.pool.StrictConnPool;
 import org.apache.hc.core5.util.Args;
@@ -128,7 +128,7 @@ public class PoolingHttpClientConnectionManager
     }
 
     public PoolingHttpClientConnectionManager(final TimeValue timeToLive) {
-        this(getDefaultRegistry(), null, null ,null, ConnPoolPolicy.LIFO, null, timeToLive);
+        this(getDefaultRegistry(), null, null ,null, PoolReusePolicy.LIFO, null, timeToLive);
     }
 
     public PoolingHttpClientConnectionManager(
@@ -157,7 +157,7 @@ public class PoolingHttpClientConnectionManager
             final Registry<ConnectionSocketFactory> socketFactoryRegistry,
             final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
             final DnsResolver dnsResolver) {
-        this(socketFactoryRegistry, connFactory, null, dnsResolver, ConnPoolPolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
+        this(socketFactoryRegistry, connFactory, null, dnsResolver, PoolReusePolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
     }
 
     public PoolingHttpClientConnectionManager(
@@ -165,24 +165,24 @@ public class PoolingHttpClientConnectionManager
             final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
             final SchemePortResolver schemePortResolver,
             final DnsResolver dnsResolver,
-            final ConnPoolPolicy connPoolPolicy,
+            final PoolReusePolicy poolReusePolicy,
             final ConnPoolListener<HttpRoute> connPoolListener,
             final TimeValue timeToLive) {
         this(new DefaultHttpClientConnectionOperator(socketFactoryRegistry, schemePortResolver, dnsResolver),
-            connFactory, connPoolPolicy, connPoolListener, timeToLive);
+            connFactory, poolReusePolicy, connPoolListener, timeToLive);
     }
 
     public PoolingHttpClientConnectionManager(
             final HttpClientConnectionOperator httpClientConnectionOperator,
             final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
-            final ConnPoolPolicy connPoolPolicy,
+            final PoolReusePolicy poolReusePolicy,
             final ConnPoolListener<HttpRoute> connPoolListener,
             final TimeValue timeToLive) {
         super();
         this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
         this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
         this.pool = new StrictConnPool<>(
-                DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, connPoolPolicy, connPoolListener);
+                DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, poolReusePolicy, connPoolListener);
         this.closed = new AtomicBoolean(false);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
index 5a3c859..76c36b3 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
@@ -39,7 +39,7 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.config.SocketConfig;
 import org.apache.hc.core5.http.io.HttpConnectionFactory;
 import org.apache.hc.core5.pool.ConnPoolListener;
-import org.apache.hc.core5.pool.ConnPoolPolicy;
+import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
@@ -74,7 +74,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
     private LayeredConnectionSocketFactory sslSocketFactory;
     private SchemePortResolver schemePortResolver;
     private DnsResolver dnsResolver;
-    private ConnPoolPolicy connPoolPolicy;
+    private PoolReusePolicy poolReusePolicy;
     private ConnPoolListener<HttpRoute> connPoolListener;
     private SocketConfig defaultSocketConfig;
 
@@ -129,10 +129,10 @@ public class PoolingHttpClientConnectionManagerBuilder {
     }
 
     /**
-     * Assigns {@link ConnPoolPolicy} value.
+     * Assigns {@link PoolReusePolicy} value.
      */
-    public final PoolingHttpClientConnectionManagerBuilder setConnPoolPolicy(final ConnPoolPolicy connPoolPolicy) {
-        this.connPoolPolicy = connPoolPolicy;
+    public final PoolingHttpClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy poolReusePolicy) {
+        this.poolReusePolicy = poolReusePolicy;
         return this;
     }
 
@@ -209,7 +209,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
                 connectionFactory,
                 schemePortResolver,
                 dnsResolver,
-                connPoolPolicy,
+                poolReusePolicy,
                 connPoolListener,
                 timeToLive != null ? timeToLive : TimeValue.NEG_ONE_MILLISECONDS);
         poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/AsyncClientConnectionOperator.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/AsyncClientConnectionOperator.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/AsyncClientConnectionOperator.java
index b2b764a..04c07e2 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/AsyncClientConnectionOperator.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/AsyncClientConnectionOperator.java
@@ -27,15 +27,14 @@
 
 package org.apache.hc.client5.http.impl.nio;
 
+import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.hc.client5.http.ConnectTimeoutException;
 import org.apache.hc.client5.http.DnsResolver;
 import org.apache.hc.client5.http.HttpHostConnectException;
 import org.apache.hc.client5.http.SchemePortResolver;
@@ -48,9 +47,7 @@ import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.reactor.ConnectionInitiator;
-import org.apache.hc.core5.reactor.SessionRequest;
-import org.apache.hc.core5.reactor.SessionRequestCallback;
-import org.apache.hc.core5.reactor.TlsCapableIOSession;
+import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 
@@ -101,16 +98,16 @@ final class AsyncClientConnectionOperator {
             void executeNext() {
                 final int index = attempt.getAndIncrement();
                 final InetSocketAddress remoteAddress = new InetSocketAddress(remoteAddresses[index], port);
-                final SessionRequest sessionRequest = connectionInitiator.connect(
+                final Future<IOSession> sessionFuture = connectionInitiator.connect(
                         host,
                         remoteAddress,
                         localAddress,
+                        connectTimeout,
                         attachment,
-                        new SessionRequestCallback() {
+                        new FutureCallback<IOSession>() {
 
                             @Override
-                            public void completed(final SessionRequest request) {
-                                final TlsCapableIOSession session = request.getSession();
+                            public void completed(final IOSession session) {
                                 final ManagedAsyncClientConnection connection = new ManagedAsyncClientConnection(session);
                                 if (tlsStrategy != null) {
                                     tlsStrategy.upgrade(
@@ -118,33 +115,31 @@ final class AsyncClientConnectionOperator {
                                             host,
                                             session.getLocalAddress(),
                                             session.getRemoteAddress(),
-                                            request.getAttachment());
+                                            attachment);
                                 }
                                 future.completed(connection);
                             }
 
                             @Override
-                            public void failed(final SessionRequest request) {
+                            public void failed(final Exception cause) {
                                 if (attempt.get() >= remoteAddresses.length) {
-                                    future.failed(new HttpHostConnectException(request.getException(), host, remoteAddresses));
+                                    if (cause instanceof IOException) {
+                                        future.failed(new HttpHostConnectException((IOException) cause, host, remoteAddresses));
+                                    } else {
+                                        future.failed(cause);
+                                    }
                                 } else {
                                     executeNext();
                                 }
                             }
 
                             @Override
-                            public void timeout(final SessionRequest request) {
-                                future.failed(new ConnectTimeoutException(new SocketException(), host, remoteAddresses));
-                            }
-
-                            @Override
-                            public void cancelled(final SessionRequest request) {
+                            public void cancelled() {
                                 future.cancel();
                             }
 
                         });
-                future.setDependency(sessionRequest);
-                sessionRequest.setConnectTimeout(connectTimeout.toMillisIntBound());
+                future.setDependency(sessionFuture);
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/ManagedAsyncClientConnection.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/ManagedAsyncClientConnection.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/ManagedAsyncClientConnection.java
index 3998aee..ef8beba 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/ManagedAsyncClientConnection.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/ManagedAsyncClientConnection.java
@@ -43,7 +43,7 @@ import org.apache.hc.core5.http.nio.command.ShutdownCommand;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.IOEventHandler;
-import org.apache.hc.core5.reactor.TlsCapableIOSession;
+import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
@@ -57,10 +57,10 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
 
     private final Logger log = LogManager.getLogger(getClass());
 
-    private final TlsCapableIOSession ioSession;
+    private final IOSession ioSession;
     private final AtomicBoolean closed;
 
-    public ManagedAsyncClientConnection(final TlsCapableIOSession ioSession) {
+    public ManagedAsyncClientConnection(final IOSession ioSession) {
         this.ioSession = ioSession;
         this.closed = new AtomicBoolean();
     }
@@ -144,17 +144,21 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
         if (log.isDebugEnabled()) {
             log.debug(getId() + ": start TLS");
         }
-        ioSession.startTls(sslContext, sslBufferManagement, initializer, verifier);
+        if (ioSession instanceof TransportSecurityLayer) {
+            ((TransportSecurityLayer) ioSession).startTls(sslContext, sslBufferManagement, initializer, verifier);
+        } else {
+            throw new UnsupportedOperationException("TLS upgrade not supported");
+        }
     }
 
     @Override
     public TlsDetails getTlsDetails() {
-        return ioSession.getTlsDetails();
+        return ioSession instanceof TransportSecurityLayer ? ((TransportSecurityLayer) ioSession).getTlsDetails() : null;
     }
 
     @Override
     public SSLSession getSSLSession() {
-        final TlsDetails tlsDetails = ioSession.getTlsDetails();
+        final TlsDetails tlsDetails = getTlsDetails();
         return tlsDetails != null ? tlsDetails.getSSLSession() : null;
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
index 25dbae9..59d37bb 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
@@ -59,8 +59,8 @@ import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.pool.ConnPoolControl;
 import org.apache.hc.core5.pool.ConnPoolListener;
-import org.apache.hc.core5.pool.ConnPoolPolicy;
 import org.apache.hc.core5.pool.PoolEntry;
+import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.pool.PoolStats;
 import org.apache.hc.core5.pool.StrictConnPool;
 import org.apache.hc.core5.reactor.ConnectionInitiator;
@@ -68,6 +68,7 @@ import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.Identifiable;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -105,10 +106,10 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
             final SchemePortResolver schemePortResolver,
             final DnsResolver dnsResolver,
             final TimeValue timeToLive,
-            final ConnPoolPolicy policy,
+            final PoolReusePolicy poolReusePolicy,
             final ConnPoolListener<HttpRoute> connPoolListener) {
         this.connectionOperator = new AsyncClientConnectionOperator(schemePortResolver, dnsResolver, tlsStrategyLookup);
-        this.pool = new StrictConnPool<>(20, 50, timeToLive, policy != null ? policy : ConnPoolPolicy.LIFO, connPoolListener);
+        this.pool = new StrictConnPool<>(20, 50, timeToLive, poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, connPoolListener);
         this.closed = new AtomicBoolean(false);
     }
 
@@ -142,7 +143,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
     public Future<AsyncConnectionEndpoint> lease(
             final HttpRoute route,
             final Object state,
-            final TimeValue timeout,
+            final Timeout timeout,
             final FutureCallback<AsyncConnectionEndpoint> callback) {
         if (log.isDebugEnabled()) {
             log.debug("Connection request: " + ConnPoolSupport.formatStats(null, route, state, pool));
@@ -381,7 +382,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
 
     /**
      * Defines period of inactivity in milliseconds after which persistent connections must
-     * be re-validated prior to being {@link #lease(HttpRoute, Object, TimeValue,
+     * be re-validated prior to being {@link #lease(HttpRoute, Object, Timeout,
      * FutureCallback)} leased} to the consumer. Non-positive value passed
      * to this method disables connection validation. This check helps detect connections
      * that have become stale (half-closed) while kept inactive in the pool.

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
index 2af512c..9a840ad 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
@@ -27,6 +27,9 @@
 
 package org.apache.hc.client5.http.impl.nio;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 import org.apache.hc.client5.http.DnsResolver;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.SchemePortResolver;
@@ -34,12 +37,9 @@ import org.apache.hc.client5.http.ssl.H2TlsStrategy;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.pool.ConnPoolListener;
-import org.apache.hc.core5.pool.ConnPoolPolicy;
+import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.util.TimeValue;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
 /**
  * Builder for {@link PoolingAsyncClientConnectionManager} instances.
  * <p>
@@ -71,7 +71,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
     private TlsStrategy tlsStrategy;
     private SchemePortResolver schemePortResolver;
     private DnsResolver dnsResolver;
-    private ConnPoolPolicy connPoolPolicy;
+    private PoolReusePolicy poolReusePolicy;
     private ConnPoolListener<HttpRoute> connPoolListener;
 
     private boolean systemProperties;
@@ -116,10 +116,10 @@ public class PoolingAsyncClientConnectionManagerBuilder {
     }
 
     /**
-     * Assigns {@link ConnPoolPolicy} value.
+     * Assigns {@link PoolReusePolicy} value.
      */
-    public final PoolingAsyncClientConnectionManagerBuilder setConnPoolPolicy(final ConnPoolPolicy connPoolPolicy) {
-        this.connPoolPolicy = connPoolPolicy;
+    public final PoolingAsyncClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy connPoolPolicy) {
+        this.poolReusePolicy = poolReusePolicy;
         return this;
     }
 
@@ -184,7 +184,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
                 schemePortResolver,
                 dnsResolver,
                 timeToLive,
-                connPoolPolicy,
+                poolReusePolicy,
                 connPoolListener);
         poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
         if (maxConnTotal > 0) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
new file mode 100644
index 0000000..8bceb6d
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractHttpClientResponseHandler.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.sync;
+
+import java.io.IOException;
+
+import org.apache.hc.client5.http.protocol.HttpResponseException;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+
+/**
+ * A generic {@link HttpClientResponseHandler} that works with the response entity
+ * for successful (2xx) responses. If the response code was &gt;= 300, the response
+ * body is consumed and an {@link HttpResponseException} is thrown.
+ * <p>
+ * If this is used with
+ * {@link org.apache.hc.client5.http.sync.HttpClient#execute(org.apache.hc.core5.http.ClassicHttpRequest,
+ * HttpClientResponseHandler)},
+ * HttpClient may handle redirects (3xx responses) internally.
+ * </p>
+ *
+ * @since 4.4
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public abstract class AbstractHttpClientResponseHandler<T> implements HttpClientResponseHandler<T> {
+
+    /**
+     * Read the entity from the response body and pass it to the entity handler
+     * method if the response was successful (a 2xx status code). If no response
+     * body exists, this returns null. If the response was unsuccessful (&gt;= 300
+     * status code), throws an {@link HttpResponseException}.
+     */
+    @Override
+    public T handleResponse(final ClassicHttpResponse response) throws IOException {
+        final HttpEntity entity = response.getEntity();
+        if (response.getCode() >= HttpStatus.SC_REDIRECTION) {
+            EntityUtils.consume(entity);
+            throw new HttpResponseException(response.getCode(), response.getReasonPhrase());
+        }
+        return entity == null ? null : handleEntity(entity);
+    }
+
+    /**
+     * Handle the response entity and transform it into the actual response
+     * object.
+     */
+    public abstract T handleEntity(HttpEntity entity) throws IOException;
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractResponseHandler.java
deleted file mode 100644
index 00ba583..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/AbstractResponseHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-
-import org.apache.hc.client5.http.protocol.HttpResponseException;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.ResponseHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-
-/**
- * A generic {@link ResponseHandler} that works with the response entity
- * for successful (2xx) responses. If the response code was &gt;= 300, the response
- * body is consumed and an {@link HttpResponseException} is thrown.
- * <p>
- * If this is used with
- * {@link org.apache.hc.client5.http.sync.HttpClient#execute(org.apache.hc.core5.http.ClassicHttpRequest,
- * ResponseHandler)},
- * HttpClient may handle redirects (3xx responses) internally.
- * </p>
- *
- * @since 4.4
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {
-
-    /**
-     * Read the entity from the response body and pass it to the entity handler
-     * method if the response was successful (a 2xx status code). If no response
-     * body exists, this returns null. If the response was unsuccessful (&gt;= 300
-     * status code), throws an {@link HttpResponseException}.
-     */
-    @Override
-    public T handleResponse(final ClassicHttpResponse response) throws IOException {
-        final HttpEntity entity = response.getEntity();
-        if (response.getCode() >= HttpStatus.SC_REDIRECTION) {
-            EntityUtils.consume(entity);
-            throw new HttpResponseException(response.getCode(), response.getReasonPhrase());
-        }
-        return entity == null ? null : handleEntity(entity);
-    }
-
-    /**
-     * Handle the response entity and transform it into the actual response
-     * object.
-     */
-    public abstract T handleEntity(HttpEntity entity) throws IOException;
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
new file mode 100644
index 0000000..d435262
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicHttpClientResponseHandler.java
@@ -0,0 +1,73 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.sync;
+
+import java.io.IOException;
+
+import org.apache.hc.client5.http.protocol.ClientProtocolException;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+
+/**
+ * A {@link org.apache.hc.core5.http.io.ResponseHandler} that returns the response body as a String
+ * for successful (2xx) responses. If the response code was &gt;= 300, the response
+ * body is consumed and an {@link org.apache.hc.client5.http.protocol.HttpResponseException} is thrown.
+ * <p>
+ * If this is used with
+ * {@link org.apache.hc.client5.http.sync.HttpClient#execute(
+ *  org.apache.hc.core5.http.ClassicHttpRequest, org.apache.hc.core5.http.io.ResponseHandler)},
+ * HttpClient may handle redirects (3xx responses) internally.
+ * </p>
+ *
+ * @since 4.0
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public class BasicHttpClientResponseHandler extends AbstractHttpClientResponseHandler<String> {
+
+    /**
+     * Returns the entity as a body as a String.
+     */
+    @Override
+    public String handleEntity(final HttpEntity entity) throws IOException {
+        try {
+            return EntityUtils.toString(entity);
+        } catch (final ParseException ex) {
+            throw new ClientProtocolException(ex);
+        }
+    }
+
+    @Override
+    public String handleResponse(final ClassicHttpResponse response) throws IOException {
+        return super.handleResponse(response);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicResponseHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicResponseHandler.java
deleted file mode 100644
index 34f6e2c..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/BasicResponseHandler.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.sync;
-
-import java.io.IOException;
-
-import org.apache.hc.client5.http.protocol.ClientProtocolException;
-import org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.ParseException;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-
-/**
- * A {@link org.apache.hc.core5.http.io.ResponseHandler} that returns the response body as a String
- * for successful (2xx) responses. If the response code was &gt;= 300, the response
- * body is consumed and an {@link org.apache.hc.client5.http.protocol.HttpResponseException} is thrown.
- * <p>
- * If this is used with
- * {@link org.apache.hc.client5.http.sync.HttpClient#execute(
- *  org.apache.hc.core5.http.ClassicHttpRequest, org.apache.hc.core5.http.io.ResponseHandler)},
- * HttpClient may handle redirects (3xx responses) internally.
- * </p>
- *
- * @since 4.0
- */
-@Contract(threading = ThreadingBehavior.IMMUTABLE)
-public class BasicResponseHandler extends AbstractResponseHandler<String> {
-
-    /**
-     * Returns the entity as a body as a String.
-     */
-    @Override
-    public String handleEntity(final HttpEntity entity) throws IOException {
-        try {
-            return EntityUtils.toString(entity);
-        } catch (final ParseException ex) {
-            throw new ClientProtocolException(ex);
-        }
-    }
-
-    @Override
-    public String handleResponse(final ClassicHttpResponse response) throws IOException {
-        return super.handleResponse(response);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
index 9a28701..17f4777 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/CloseableHttpClient.java
@@ -41,7 +41,7 @@ import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.util.Args;
@@ -126,11 +126,11 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      * response using the given response handler. The content entity associated
      * with the response is fully consumed and the underlying connection is
      * released back to the connection manager automatically in all cases
-     * relieving individual {@link ResponseHandler}s from having to manage
+     * relieving individual {@link HttpClientResponseHandler}s from having to manage
      * resource deallocation internally.
      *
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      *
      * @return  the response object as generated by the response handler.
      * @throws IOException in case of a problem or the connection was aborted
@@ -138,8 +138,8 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      */
     @Override
     public <T> T execute(final ClassicHttpRequest request,
-            final ResponseHandler<? extends T> responseHandler) throws IOException {
-        return execute(request, responseHandler, null);
+            final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
+        return execute(request, HttpClientResponseHandler, null);
     }
 
     /**
@@ -147,11 +147,11 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      * response using the given response handler. The content entity associated
      * with the response is fully consumed and the underlying connection is
      * released back to the connection manager automatically in all cases
-     * relieving individual {@link ResponseHandler}s from having to manage
+     * relieving individual {@link HttpClientResponseHandler}s from having to manage
      * resource deallocation internally.
      *
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      * @param context   the context to use for the execution, or
      *                  {@code null} to use the default context
      *
@@ -161,10 +161,10 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      */
     @Override
     public <T> T execute(final ClassicHttpRequest request,
-            final ResponseHandler<? extends T> responseHandler, final HttpContext context)
+            final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context)
             throws IOException {
         final HttpHost target = determineTarget(request);
-        return execute(target, request, responseHandler, context);
+        return execute(target, request, HttpClientResponseHandler, context);
     }
 
     /**
@@ -172,7 +172,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      * response using the given response handler. The content entity associated
      * with the response is fully consumed and the underlying connection is
      * released back to the connection manager automatically in all cases
-     * relieving individual {@link ResponseHandler}s from having to manage
+     * relieving individual {@link HttpClientResponseHandler}s from having to manage
      * resource deallocation internally.
      *
      * @param target    the target host for the request.
@@ -180,7 +180,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      *                  if they can still determine a route, for example
      *                  to a default target or by inspecting the request.
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      *
      * @return  the response object as generated by the response handler.
      * @throws IOException in case of a problem or the connection was aborted
@@ -188,8 +188,8 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      */
     @Override
     public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
-            final ResponseHandler<? extends T> responseHandler) throws IOException {
-        return execute(target, request, responseHandler, null);
+            final HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException {
+        return execute(target, request, HttpClientResponseHandler, null);
     }
 
     /**
@@ -197,7 +197,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      * response using the given response handler. The content entity associated
      * with the response is fully consumed and the underlying connection is
      * released back to the connection manager automatically in all cases
-     * relieving individual {@link ResponseHandler}s from having to manage
+     * relieving individual {@link HttpClientResponseHandler}s from having to manage
      * resource deallocation internally.
      *
      * @param target    the target host for the request.
@@ -205,7 +205,7 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      *                  if they can still determine a route, for example
      *                  to a default target or by inspecting the request.
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      * @param context   the context to use for the execution, or
      *                  {@code null} to use the default context
      *
@@ -215,12 +215,12 @@ public abstract class CloseableHttpClient implements HttpClient, Closeable {
      */
     @Override
     public <T> T execute(final HttpHost target, final ClassicHttpRequest request,
-            final ResponseHandler<? extends T> responseHandler, final HttpContext context) throws IOException {
-        Args.notNull(responseHandler, "Response handler");
+            final HttpClientResponseHandler<? extends T> HttpClientResponseHandler, final HttpContext context) throws IOException {
+        Args.notNull(HttpClientResponseHandler, "Response handler");
 
         try (final CloseableHttpResponse response = execute(target, request, context)) {
             try {
-                final T result = responseHandler.handleResponse(response);
+                final T result = HttpClientResponseHandler.handleResponse(response);
                 final HttpEntity entity = response.getEntity();
                 EntityUtils.consume(entity);
                 return result;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
index 7601d74..acd3f49 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/FutureRequestExecutionService.java
@@ -36,7 +36,7 @@ import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 /**
@@ -78,15 +78,15 @@ public class FutureRequestExecutionService implements Closeable {
      *
      * @param request
      *            request to execute
-     * @param responseHandler
+     * @param HttpClientResponseHandler
      *            handler that will process the response.
      * @return HttpAsyncClientFutureTask for the scheduled request.
      */
     public <T> HttpRequestFutureTask<T> execute(
             final ClassicHttpRequest request,
             final HttpContext context,
-            final ResponseHandler<T> responseHandler) {
-        return execute(request, context, responseHandler, null);
+            final HttpClientResponseHandler<T> HttpClientResponseHandler) {
+        return execute(request, context, HttpClientResponseHandler, null);
     }
 
     /**
@@ -98,7 +98,7 @@ public class FutureRequestExecutionService implements Closeable {
      *            request to execute
      * @param context
      *            optional context; use null if not needed.
-     * @param responseHandler
+     * @param HttpClientResponseHandler
      *            handler that will process the response.
      * @param callback
      *            callback handler that will be called when the request is scheduled,
@@ -108,14 +108,14 @@ public class FutureRequestExecutionService implements Closeable {
     public <T> HttpRequestFutureTask<T> execute(
             final ClassicHttpRequest request,
             final HttpContext context,
-            final ResponseHandler<T> responseHandler,
+            final HttpClientResponseHandler<T> HttpClientResponseHandler,
             final FutureCallback<T> callback) {
         if(closed.get()) {
             throw new IllegalStateException("Close has been called on this httpclient instance.");
         }
         metrics.getScheduledConnections().incrementAndGet();
         final HttpRequestTaskCallable<T> callable = new HttpRequestTaskCallable<>(
-                httpclient, request, context, responseHandler, callback, metrics);
+                httpclient, request, context, HttpClientResponseHandler, callback, metrics);
         final HttpRequestFutureTask<T> httpRequestFutureTask = new HttpRequestFutureTask<>(
                 request, callable);
         executorService.execute(httpRequestFutureTask);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java
index af94d36..113d107 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpClientBuilder.java
@@ -53,7 +53,6 @@ import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
 import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
 import org.apache.hc.client5.http.impl.DefaultUserTokenHandler;
 import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
-import org.apache.hc.client5.http.impl.NamedElementChain;
 import org.apache.hc.client5.http.impl.NoopUserTokenHandler;
 import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
 import org.apache.hc.client5.http.impl.auth.CredSspSchemeFactory;
@@ -93,6 +92,7 @@ import org.apache.hc.core5.http.HttpRequestInterceptor;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.config.Lookup;
+import org.apache.hc.core5.http.config.NamedElementChain;
 import org.apache.hc.core5.http.config.Registry;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java
index 695727d..ac7696b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/sync/HttpRequestTaskCallable.java
@@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.hc.client5.http.sync.HttpClient;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 class HttpRequestTaskCallable<V> implements Callable<V> {
@@ -46,7 +46,7 @@ class HttpRequestTaskCallable<V> implements Callable<V> {
     private long ended = -1;
 
     private final HttpContext context;
-    private final ResponseHandler<V> responseHandler;
+    private final HttpClientResponseHandler<V> responseHandler;
     private final FutureCallback<V> callback;
 
     private final FutureRequestExecutionMetrics metrics;
@@ -55,7 +55,7 @@ class HttpRequestTaskCallable<V> implements Callable<V> {
             final HttpClient httpClient,
             final ClassicHttpRequest request,
             final HttpContext context,
-            final ResponseHandler<V> responseHandler,
+            final HttpClientResponseHandler<V> responseHandler,
             final FutureCallback<V> callback,
             final FutureRequestExecutionMetrics metrics) {
         this.httpclient = httpClient;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/nio/AsyncClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/nio/AsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/nio/AsyncClientConnectionManager.java
index 6318989..1b119bf 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/nio/AsyncClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/nio/AsyncClientConnectionManager.java
@@ -34,6 +34,7 @@ import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.reactor.ConnectionInitiator;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Represents a manager of persistent non-blocking client connections.
@@ -76,7 +77,7 @@ public interface AsyncClientConnectionManager extends Closeable {
     Future<AsyncConnectionEndpoint> lease(
             HttpRoute route,
             Object state,
-            TimeValue timeout,
+            Timeout timeout,
             FutureCallback<AsyncConnectionEndpoint> callback);
 
     /**

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/sync/HttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/sync/HttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/sync/HttpClient.java
index 26fb3b1..befa7ae 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/sync/HttpClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/sync/HttpClient.java
@@ -33,7 +33,7 @@ import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 
 /**
@@ -121,17 +121,17 @@ public interface HttpClient {
      * Implementing classes are required to ensure that the content entity
      * associated with the response is fully consumed and the underlying
      * connection is released back to the connection manager automatically
-     * in all cases relieving individual {@link ResponseHandler}s from
+     * in all cases relieving individual {@link HttpClientResponseHandler}s from
      * having to manage resource deallocation internally.
      * </p>
      *
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      *
      * @return  the response object as generated by the response handler.
      * @throws IOException in case of a problem or the connection was aborted
      */
-    <T> T execute(ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException;
+    <T> T execute(ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException;
 
     /**
      * Executes HTTP request using the given context and processes the
@@ -140,19 +140,19 @@ public interface HttpClient {
      * Implementing classes are required to ensure that the content entity
      * associated with the response is fully consumed and the underlying
      * connection is released back to the connection manager automatically
-     * in all cases relieving individual {@link ResponseHandler}s from
+     * in all cases relieving individual {@link HttpClientResponseHandler}s from
      * having to manage resource deallocation internally.
      * </p>
      *
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      * @param context   the context to use for the execution, or
      *                  {@code null} to use the default context
      *
      * @return  the response object as generated by the response handler.
      * @throws IOException in case of a problem or the connection was aborted
      */
-    <T> T execute(ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException;
+    <T> T execute(ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler, HttpContext context) throws IOException;
 
     /**
      * Executes HTTP request to the target using the default context and
@@ -161,7 +161,7 @@ public interface HttpClient {
      * Implementing classes are required to ensure that the content entity
      * associated with the response is fully consumed and the underlying
      * connection is released back to the connection manager automatically
-     * in all cases relieving individual {@link ResponseHandler}s from
+     * in all cases relieving individual {@link HttpClientResponseHandler}s from
      * having to manage resource deallocation internally.
      * </p>
      *
@@ -170,12 +170,12 @@ public interface HttpClient {
      *                  if they can still determine a route, for example
      *                  to a default target or by inspecting the request.
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      *
      * @return  the response object as generated by the response handler.
      * @throws IOException in case of a problem or the connection was aborted
      */
-    <T> T execute(HttpHost target, ClassicHttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException;
+    <T> T execute(HttpHost target, ClassicHttpRequest request, HttpClientResponseHandler<? extends T> HttpClientResponseHandler) throws IOException;
 
     /**
      * Executes HTTP request to the target using the given context and
@@ -184,7 +184,7 @@ public interface HttpClient {
      * Implementing classes are required to ensure that the content entity
      * associated with the response is fully consumed and the underlying
      * connection is released back to the connection manager automatically
-     * in all cases relieving individual {@link ResponseHandler}s from
+     * in all cases relieving individual {@link HttpClientResponseHandler}s from
      * having to manage resource deallocation internally.
      * </p>
      *
@@ -193,7 +193,7 @@ public interface HttpClient {
      *                  if they can still determine a route, for example
      *                  to a default target or by inspecting the request.
      * @param request   the request to execute
-     * @param responseHandler the response handler
+     * @param HttpClientResponseHandler the response handler
      * @param context   the context to use for the execution, or
      *                  {@code null} to use the default context
      *
@@ -203,7 +203,7 @@ public interface HttpClient {
     <T> T execute(
             HttpHost target,
             ClassicHttpRequest request,
-            ResponseHandler<? extends T> responseHandler,
+            HttpClientResponseHandler<? extends T> HttpClientResponseHandler,
             HttpContext context) throws IOException;
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java b/httpclient5/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java
index ba81be2..d22bbe3 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/utils/URIUtils.java
@@ -77,7 +77,7 @@ public class URIUtils {
             uribuilder.setPort(target.getPort());
         } else {
             uribuilder.setScheme(null);
-            uribuilder.setHost(null);
+            uribuilder.setHost((String) null);
             uribuilder.setPort(-1);
         }
         if (dropFragment) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/config/TestRequestConfig.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/config/TestRequestConfig.java b/httpclient5/src/test/java/org/apache/hc/client5/http/config/TestRequestConfig.java
index fab90d8..36a8558 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/config/TestRequestConfig.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/config/TestRequestConfig.java
@@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -47,9 +48,9 @@ public class TestRequestConfig {
     @Test
     public void testDefaults() {
         final RequestConfig config = RequestConfig.DEFAULT;
-        Assert.assertEquals(TimeValue.NEG_ONE_MILLISECONDS, config.getSocketTimeout());
-        Assert.assertEquals(TimeValue.ofMinutes(3), config.getConnectTimeout());
-        Assert.assertEquals(TimeValue.ofMinutes(3), config.getConnectionRequestTimeout());
+        Assert.assertEquals(Timeout.ZERO_MILLISECONDS, config.getSocketTimeout());
+        Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectTimeout());
+        Assert.assertEquals(Timeout.ofMinutes(3), config.getConnectionRequestTimeout());
         Assert.assertEquals(false, config.isExpectContinueEnabled());
         Assert.assertEquals(true, config.isAuthenticationEnabled());
         Assert.assertEquals(true, config.isRedirectsEnabled());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
new file mode 100644
index 0000000..44a48ba
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
@@ -0,0 +1,89 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.hc.client5.http.impl.sync.AbstractHttpClientResponseHandler;
+import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
+import org.apache.hc.client5.http.protocol.HttpResponseException;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link BasicHttpClientResponseHandler}.
+ */
+public class TestAbstractHttpClientResponseHandler {
+
+    @Test
+    public void testSuccessfulResponse() throws Exception {
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        final HttpEntity entity = new StringEntity("42");
+        Mockito.when(response.getCode()).thenReturn(200);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final AbstractHttpClientResponseHandler<Integer> handler = new AbstractHttpClientResponseHandler<Integer>() {
+
+          @Override
+          public Integer handleEntity(final HttpEntity entity) throws IOException {
+            return Integer.valueOf(new String(EntityUtils.toByteArray(entity)));
+          }
+        };
+        final Integer number = handler.handleResponse(response);
+        Assert.assertEquals(42, number.intValue());
+    }
+
+    @SuppressWarnings("boxing")
+    @Test
+    public void testUnsuccessfulResponse() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
+        Mockito.when(entity.isStreaming()).thenReturn(true);
+        Mockito.when(entity.getContent()).thenReturn(instream);
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        Mockito.when(response.getCode()).thenReturn(404);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
+        try {
+            handler.handleResponse(response);
+            Assert.fail("HttpResponseException expected");
+        } catch (final HttpResponseException ex) {
+            Assert.assertEquals(404, ex.getStatusCode());
+        }
+        Mockito.verify(entity).getContent();
+        Mockito.verify(instream).close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractResponseHandler.java
deleted file mode 100644
index cb12818..0000000
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractResponseHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.hc.client5.http.impl.sync.AbstractResponseHandler;
-import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
-import org.apache.hc.client5.http.protocol.HttpResponseException;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Unit tests for {@link BasicResponseHandler}.
- */
-public class TestAbstractResponseHandler {
-
-    @Test
-    public void testSuccessfulResponse() throws Exception {
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        final HttpEntity entity = new StringEntity("42");
-        Mockito.when(response.getCode()).thenReturn(200);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final AbstractResponseHandler<Integer> handler = new AbstractResponseHandler<Integer>() {
-
-          @Override
-          public Integer handleEntity(final HttpEntity entity) throws IOException {
-            return Integer.valueOf(new String(EntityUtils.toByteArray(entity)));
-          }
-        };
-        final Integer number = handler.handleResponse(response);
-        Assert.assertEquals(42, number.intValue());
-    }
-
-    @SuppressWarnings("boxing")
-    @Test
-    public void testUnsuccessfulResponse() throws Exception {
-        final InputStream instream = Mockito.mock(InputStream.class);
-        final HttpEntity entity = Mockito.mock(HttpEntity.class);
-        Mockito.when(entity.isStreaming()).thenReturn(true);
-        Mockito.when(entity.getContent()).thenReturn(instream);
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        Mockito.when(response.getCode()).thenReturn(404);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final BasicResponseHandler handler = new BasicResponseHandler();
-        try {
-            handler.handleResponse(response);
-            Assert.fail("HttpResponseException expected");
-        } catch (final HttpResponseException ex) {
-            Assert.assertEquals(404, ex.getStatusCode());
-        }
-        Mockito.verify(entity).getContent();
-        Mockito.verify(instream).close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
index db8c1b7..f8d5abb 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
@@ -29,7 +29,7 @@ package org.apache.hc.client5.http.impl;
 
 import java.io.InputStream;
 
-import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
+import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
 import org.apache.hc.client5.http.protocol.HttpResponseException;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpEntity;
@@ -39,7 +39,7 @@ import org.junit.Test;
 import org.mockito.Mockito;
 
 /**
- * Unit tests for {@link BasicResponseHandler}.
+ * Unit tests for {@link BasicHttpClientResponseHandler}.
  */
 @SuppressWarnings("boxing") // test code
 public class TestBasicResponseHandler {
@@ -51,7 +51,7 @@ public class TestBasicResponseHandler {
         Mockito.when(response.getCode()).thenReturn(200);
         Mockito.when(response.getEntity()).thenReturn(entity);
 
-        final BasicResponseHandler handler = new BasicResponseHandler();
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
         final String s = handler.handleResponse(response);
         Assert.assertEquals("stuff", s);
     }
@@ -66,7 +66,7 @@ public class TestBasicResponseHandler {
         Mockito.when(response.getCode()).thenReturn(404);
         Mockito.when(response.getEntity()).thenReturn(entity);
 
-        final BasicResponseHandler handler = new BasicResponseHandler();
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
         try {
             handler.handleResponse(response);
             Assert.fail("HttpResponseException expected");

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestNamedElementChain.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestNamedElementChain.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestNamedElementChain.java
deleted file mode 100644
index fb48ca9..0000000
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestNamedElementChain.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests for {@link NamedElementChain}.
- */
-public class TestNamedElementChain {
-
-    @Test
-    public void testBasics() {
-        final NamedElementChain<Character> list = new NamedElementChain<>();
-        Assert.assertThat(list.getFirst(), CoreMatchers.nullValue());
-        Assert.assertThat(list.getLast(), CoreMatchers.nullValue());
-
-        final NamedElementChain<Character>.Node nodeA = list.addFirst('a', "a");
-
-        Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
-        Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeA));
-
-        final NamedElementChain<Character>.Node nodeB = list.addLast('b', "b");
-
-        Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
-        Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeB));
-
-        final NamedElementChain<Character>.Node nodeZ = list.addLast('z', "z");
-
-        Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeA));
-        Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeZ));
-
-        Assert.assertThat(nodeA.getPrevious(), CoreMatchers.nullValue());
-        Assert.assertThat(nodeA.getNext(), CoreMatchers.sameInstance(nodeB));
-        Assert.assertThat(nodeB.getPrevious(), CoreMatchers.sameInstance(nodeA));
-        Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeZ));
-        Assert.assertThat(nodeZ.getPrevious(), CoreMatchers.sameInstance(nodeB));
-        Assert.assertThat(nodeZ.getNext(), CoreMatchers.nullValue());
-
-        final NamedElementChain<Character>.Node nodeD = list.addAfter("b", 'd', "d");
-        Assert.assertThat(nodeD.getPrevious(), CoreMatchers.sameInstance(nodeB));
-        Assert.assertThat(nodeD.getNext(), CoreMatchers.sameInstance(nodeZ));
-        Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeD));
-        Assert.assertThat(nodeZ.getPrevious(), CoreMatchers.sameInstance(nodeD));
-
-        final NamedElementChain<Character>.Node nodeC = list.addBefore("d", 'c', "c");
-        Assert.assertThat(nodeC.getPrevious(), CoreMatchers.sameInstance(nodeB));
-        Assert.assertThat(nodeC.getNext(), CoreMatchers.sameInstance(nodeD));
-        Assert.assertThat(nodeB.getNext(), CoreMatchers.sameInstance(nodeC));
-        Assert.assertThat(nodeD.getPrevious(), CoreMatchers.sameInstance(nodeC));
-        Assert.assertThat(list.getSize(), CoreMatchers.equalTo(5));
-
-        Assert.assertThat(list.remove("a"), CoreMatchers.is(true));
-        Assert.assertThat(list.remove("z"), CoreMatchers.is(true));
-        Assert.assertThat(list.remove("c"), CoreMatchers.is(true));
-        Assert.assertThat(list.remove("c"), CoreMatchers.is(false));
-        Assert.assertThat(list.remove("blah"), CoreMatchers.is(false));
-
-        Assert.assertThat(list.getFirst(), CoreMatchers.sameInstance(nodeB));
-        Assert.assertThat(list.getLast(), CoreMatchers.sameInstance(nodeD));
-
-        Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
-        Assert.assertThat(list.addBefore("blah", 'e', "e"), CoreMatchers.nullValue());
-        Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
-
-        Assert.assertThat(list.addAfter("yada", 'e', "e"), CoreMatchers.nullValue());
-        Assert.assertThat(list.getSize(), CoreMatchers.equalTo(2));
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestCloseableHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestCloseableHttpClient.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestCloseableHttpClient.java
index 7d8299c..99687d6 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestCloseableHttpClient.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/sync/TestCloseableHttpClient.java
@@ -35,7 +35,7 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assert;
 import org.junit.Before;
@@ -119,7 +119,7 @@ public class TestCloseableHttpClient {
         Mockito.when(client.doExecute(
                 new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
 
-        final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
+        final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
 
         client.execute(httpget, handler);
 
@@ -139,7 +139,7 @@ public class TestCloseableHttpClient {
         Mockito.when(client.doExecute(
                 new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
 
-        final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
+        final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
 
         Mockito.when(handler.handleResponse(response)).thenThrow(new IOException());
 
@@ -163,7 +163,7 @@ public class TestCloseableHttpClient {
         Mockito.when(client.doExecute(
                 new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
 
-        final ResponseHandler<HttpResponse> handler = Mockito.mock(ResponseHandler.class);
+        final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
 
         Mockito.when(handler.handleResponse(response)).thenThrow(new RuntimeException());
 


[5/6] httpcomponents-client git commit: Upgraded HttpCore to version 5.0-alpha4

Posted by ol...@apache.org.
Upgraded HttpCore to version 5.0-alpha4


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/1eb22180
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/1eb22180
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/1eb22180

Branch: refs/heads/master
Commit: 1eb221808f037b1c7242d0b4c092e5c3eea49edf
Parents: 272ea1f
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Tue Aug 29 16:12:38 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Sep 1 17:39:24 2017 +0200

----------------------------------------------------------------------
 .../impl/cache/CachingHttpClientBuilder.java    |   2 +-
 .../http/impl/cache/TestCachingExecChain.java   |   9 +-
 ...taleWhileRevalidationReleasesConnection.java |   2 +-
 .../http/examples/fluent/FluentExecutor.java    |   6 +-
 .../http/examples/fluent/FluentRequests.java    |   6 +-
 .../examples/fluent/FluentResponseHandling.java |   4 +-
 .../apache/hc/client5/http/fluent/Async.java    |  10 +-
 .../http/fluent/ContentResponseHandler.java     |   4 +-
 .../apache/hc/client5/http/fluent/Request.java  |  10 +-
 .../apache/hc/client5/http/fluent/Response.java |   7 +-
 .../AbstractSimpleServerExchangeHandler.java    |   8 +-
 .../client5/testing/async/AsyncEchoHandler.java |   4 +-
 .../testing/async/AsyncRandomHandler.java       |   4 +-
 .../async/AuthenticatingAsyncDecorator.java     | 181 ++++++++
 .../hc/client5/testing/auth/Authenticator.java  |  38 ++
 .../testing/auth/BasicAuthTokenExtractor.java   |  29 +-
 .../client5/testing/auth/RequestBasicAuth.java  |  55 ---
 .../testing/auth/ResponseBasicUnauthorized.java |  54 ---
 .../classic/AuthenticatingDecorator.java        | 105 +++++
 .../client5/testing/BasicTestAuthenticator.java |  54 +++
 .../testing/async/IntegrationTestBase.java      |  22 +-
 .../testing/async/TestAsyncRedirects.java       |   4 +-
 .../testing/async/TestClientAuthentication.java | 228 ++++------
 .../testing/async/TestHttpAsyncMinimal.java     |   6 +-
 .../hc/client5/testing/fluent/TestFluent.java   |  11 +-
 .../testing/sync/LocalServerTestBase.java       | 115 +++--
 .../testing/sync/TestClientAuthentication.java  | 424 +++++++++++--------
 .../sync/TestClientAuthenticationFakeNTLM.java  |  10 +-
 .../sync/TestClientAuthenticationFallBack.java  | 148 -------
 .../sync/TestClientReauthentication.java        | 188 --------
 .../sync/TestClientRequestExecution.java        |  10 +-
 .../testing/sync/TestConnectionAutoRelease.java | 229 ----------
 .../testing/sync/TestConnectionReuse.java       |  33 +-
 .../testing/sync/TestContentCodings.java        |  24 +-
 .../testing/sync/TestCookieVirtualHost.java     |   2 +-
 .../sync/TestMalformedServerResponse.java       |  73 ++--
 .../sync/TestMinimalClientRequestExecution.java |   2 +-
 .../hc/client5/testing/sync/TestRedirects.java  | 200 +++++----
 .../client5/testing/sync/TestSPNegoScheme.java  |   4 +-
 .../sync/TestStatefulConnManagement.java        |   6 +-
 .../sync/TestWindowsNegotiateScheme.java        |  18 +-
 .../examples/AsyncClientConnectionEviction.java |   3 +-
 .../examples/AsyncClientHttp1Pipelining.java    |   4 +-
 .../examples/AsyncClientHttp2Multiplexing.java  |   4 +-
 .../examples/AsyncClientHttp2ServerPush.java    |   4 +-
 .../http/examples/AsyncClientHttpExchange.java  |   4 +-
 .../AsyncClientHttpExchangeStreaming.java       |   4 +-
 .../http/examples/AsyncClientInterceptors.java  |   4 +-
 .../examples/AsyncClientMessageTrailers.java    |   4 +-
 .../http/examples/ClientConfiguration.java      |   7 +-
 .../http/examples/ClientWithRequestFuture.java  |   6 +-
 .../examples/ClientWithResponseHandler.java     |   6 +-
 .../hc/client5/http/config/RequestConfig.java   |  44 +-
 .../hc/client5/http/impl/NamedElementChain.java | 212 ----------
 .../impl/async/AbstractHttpAsyncClientBase.java |  20 +-
 .../impl/async/BasicAsyncEntityProducer.java    |  94 ----
 .../impl/async/CloseableHttpAsyncClient.java    |   2 +-
 .../http/impl/async/HttpAsyncClientBuilder.java |  32 +-
 .../HttpAsyncClientEventHandlerFactory.java     |  39 +-
 .../http/impl/async/HttpAsyncClients.java       |  21 +-
 .../impl/async/InternalAsyncEntityProducer.java |  93 ++++
 .../impl/async/InternalHttpAsyncClient.java     |  10 +-
 .../http/impl/async/MinimalHttpAsyncClient.java | 122 +++---
 .../io/PoolingHttpClientConnectionManager.java  |  14 +-
 ...olingHttpClientConnectionManagerBuilder.java |  12 +-
 .../impl/nio/AsyncClientConnectionOperator.java |  35 +-
 .../impl/nio/ManagedAsyncClientConnection.java  |  16 +-
 .../PoolingAsyncClientConnectionManager.java    |  11 +-
 ...lingAsyncClientConnectionManagerBuilder.java |  18 +-
 .../sync/AbstractHttpClientResponseHandler.java |  79 ++++
 .../http/impl/sync/AbstractResponseHandler.java |  79 ----
 .../sync/BasicHttpClientResponseHandler.java    |  73 ++++
 .../http/impl/sync/BasicResponseHandler.java    |  73 ----
 .../http/impl/sync/CloseableHttpClient.java     |  36 +-
 .../sync/FutureRequestExecutionService.java     |  14 +-
 .../http/impl/sync/HttpClientBuilder.java       |   2 +-
 .../http/impl/sync/HttpRequestTaskCallable.java |   6 +-
 .../http/nio/AsyncClientConnectionManager.java  |   3 +-
 .../apache/hc/client5/http/sync/HttpClient.java |  26 +-
 .../apache/hc/client5/http/utils/URIUtils.java  |   2 +-
 .../client5/http/config/TestRequestConfig.java  |   7 +-
 .../TestAbstractHttpClientResponseHandler.java  |  89 ++++
 .../http/impl/TestAbstractResponseHandler.java  |  89 ----
 .../http/impl/TestBasicResponseHandler.java     |   8 +-
 .../http/impl/TestNamedElementChain.java        |  97 -----
 .../http/impl/sync/TestCloseableHttpClient.java |   8 +-
 .../sync/TestFutureRequestExecutionService.java |   6 +-
 pom.xml                                         |   2 +-
 88 files changed, 1651 insertions(+), 2242 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
index 052b6ff..e734523 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
@@ -33,10 +33,10 @@ import java.io.IOException;
 import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
 import org.apache.hc.client5.http.cache.ResourceFactory;
-import org.apache.hc.client5.http.impl.NamedElementChain;
 import org.apache.hc.client5.http.impl.sync.ChainElements;
 import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
 import org.apache.hc.client5.http.sync.ExecChainHandler;
+import org.apache.hc.core5.http.config.NamedElementChain;
 
 /**
  * Builder for {@link org.apache.hc.client5.http.impl.sync.CloseableHttpClient}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
index 00d3747..fcf05f2 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExecChain.java
@@ -47,7 +47,6 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-import junit.framework.AssertionFailedError;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.cache.CacheResponseStatus;
 import org.apache.hc.client5.http.cache.HttpCacheContext;
@@ -71,7 +70,7 @@ import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
@@ -85,6 +84,8 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import junit.framework.AssertionFailedError;
+
 @SuppressWarnings("boxing") // test code
 public abstract class TestCachingExecChain {
 
@@ -100,7 +101,7 @@ public abstract class TestCachingExecChain {
     protected ResponseCachingPolicy mockResponsePolicy;
     protected HttpCacheEntry mockCacheEntry;
     protected CachedHttpResponseGenerator mockResponseGenerator;
-    private ResponseHandler<Object> mockHandler;
+    private HttpClientResponseHandler<Object> mockHandler;
     private ClassicHttpRequest mockUriRequest;
     private ClassicHttpResponse mockCachedResponse;
     protected ConditionalRequestBuilder mockConditionalRequestBuilder;
@@ -126,7 +127,7 @@ public abstract class TestCachingExecChain {
         mockCache = createNiceMock(HttpCache.class);
         mockSuitabilityChecker = createNiceMock(CachedResponseSuitabilityChecker.class);
         mockResponsePolicy = createNiceMock(ResponseCachingPolicy.class);
-        mockHandler = createNiceMock(ResponseHandler.class);
+        mockHandler = createNiceMock(HttpClientResponseHandler.class);
         mockUriRequest = createNiceMock(ClassicHttpRequest.class);
         mockCacheEntry = createNiceMock(HttpCacheEntry.class);
         mockResponseGenerator = createNiceMock(CachedHttpResponseGenerator.class);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestStaleWhileRevalidationReleasesConnection.java
----------------------------------------------------------------------
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestStaleWhileRevalidationReleasesConnection.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestStaleWhileRevalidationReleasesConnection.java
index ee59498..83b06d7 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestStaleWhileRevalidationReleasesConnection.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestStaleWhileRevalidationReleasesConnection.java
@@ -81,7 +81,7 @@ public class TestStaleWhileRevalidationReleasesConnection {
                 .setSocketConfig(SocketConfig.custom()
                         .setSoTimeout(5, TimeUnit.SECONDS)
                         .build())
-                .registerHandler(url + "*", new EchoViaHeaderHandler())
+                .register(url + "*", new EchoViaHeaderHandler())
                 .create();
         this.localServer.start();
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentExecutor.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentExecutor.java b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentExecutor.java
index 1a4e16a..c6ccccf 100644
--- a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentExecutor.java
+++ b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentExecutor.java
@@ -34,7 +34,7 @@ import org.apache.hc.client5.http.fluent.Request;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates how the he HttpClient fluent API can be used to execute multiple
@@ -52,8 +52,8 @@ public class FluentExecutor {
 
         // Execute a GET with timeout settings and return response content as String.
         executor.execute(Request.Get("http://somehost/")
-                .connectTimeout(TimeValue.ofSeconds(1))
-                .socketTimeout(TimeValue.ofSeconds(1))
+                .connectTimeout(Timeout.ofSeconds(1))
+                .socketTimeout(Timeout.ofSeconds(1))
                 ).returnContent().asString();
 
         // Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentRequests.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentRequests.java b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentRequests.java
index b1aa399..520dd62 100644
--- a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentRequests.java
+++ b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentRequests.java
@@ -33,7 +33,7 @@ import org.apache.hc.client5.http.fluent.Request;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates basics of request execution with the HttpClient fluent API.
@@ -43,8 +43,8 @@ public class FluentRequests {
     public static void main(String[] args)throws Exception {
         // Execute a GET with timeout settings and return response content as String.
         Request.Get("http://somehost/")
-                .connectTimeout(TimeValue.ofSeconds(1))
-                .socketTimeout(TimeValue.ofSeconds(1))
+                .connectTimeout(Timeout.ofSeconds(1))
+                .socketTimeout(Timeout.ofSeconds(1))
                 .execute().returnContent().asString();
 
         // Execute a POST with the 'expect-continue' handshake, using HTTP/1.1,

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
index b989eaa..fe62aae 100644
--- a/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
+++ b/httpclient5-fluent/src/examples/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
@@ -41,7 +41,7 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
@@ -54,7 +54,7 @@ public class FluentResponseHandling {
 
     public static void main(String[] args)throws Exception {
         Document result = Request.Get("http://somehost/content")
-                .execute().handleResponse(new ResponseHandler<Document>() {
+                .execute().handleResponse(new HttpClientResponseHandler<Document>() {
 
             @Override
             public Document handleResponse(final ClassicHttpResponse response) throws IOException {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Async.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Async.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Async.java
index 7c6462d..beb710b 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Async.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Async.java
@@ -30,7 +30,7 @@ import java.util.concurrent.Future;
 
 import org.apache.hc.core5.concurrent.BasicFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 
 public class Async {
 
@@ -60,13 +60,13 @@ public class Async {
         private final BasicFuture<T> future;
         private final Request request;
         private final Executor executor;
-        private final ResponseHandler<T> handler;
+        private final HttpClientResponseHandler<T> handler;
 
         ExecRunnable(
                 final BasicFuture<T> future,
                 final Request request,
                 final Executor executor,
-                final ResponseHandler<T> handler) {
+                final HttpClientResponseHandler<T> handler) {
             super();
             this.future = future;
             this.request = request;
@@ -88,7 +88,7 @@ public class Async {
     }
 
     public <T> Future<T> execute(
-            final Request request, final ResponseHandler<T> handler, final FutureCallback<T> callback) {
+            final Request request, final HttpClientResponseHandler<T> handler, final FutureCallback<T> callback) {
         final BasicFuture<T> future = new BasicFuture<>(callback);
         final ExecRunnable<T> runnable = new ExecRunnable<>(
                 future,
@@ -105,7 +105,7 @@ public class Async {
         return future;
     }
 
-    public <T> Future<T> execute(final Request request, final ResponseHandler<T> handler) {
+    public <T> Future<T> execute(final Request request, final HttpClientResponseHandler<T> handler) {
         return execute(request, handler, null);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
index 77cde47..6954891 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
@@ -28,7 +28,7 @@ package org.apache.hc.client5.http.fluent;
 
 import java.io.IOException;
 
-import org.apache.hc.client5.http.impl.sync.AbstractResponseHandler;
+import org.apache.hc.client5.http.impl.sync.AbstractHttpClientResponseHandler;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 
@@ -41,7 +41,7 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
  *
  * @since 4.4
  */
-public class ContentResponseHandler extends AbstractResponseHandler<Content> {
+public class ContentResponseHandler extends AbstractHttpClientResponseHandler<Content> {
 
     @Override
     public Content handleEntity(final HttpEntity entity) throws IOException {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
index 8d1b1f2..533f321 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
@@ -66,7 +66,7 @@ import org.apache.hc.core5.http.io.entity.FileEntity;
 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.net.URLEncodedUtils;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 public class Request {
 
@@ -76,8 +76,8 @@ public class Request {
 
     private final HttpUriRequestBase request;
     private Boolean useExpectContinue;
-    private TimeValue socketTmeout;
-    private TimeValue connectTimeout;
+    private Timeout socketTmeout;
+    private Timeout connectTimeout;
     private HttpHost proxy;
 
     private SimpleDateFormat dateFormatter;
@@ -283,12 +283,12 @@ public class Request {
 
     //// HTTP connection parameter operations
 
-    public Request socketTimeout(final TimeValue timeout) {
+    public Request socketTimeout(final Timeout timeout) {
         this.socketTmeout = timeout;
         return this;
     }
 
-    public Request connectTimeout(final TimeValue timeout) {
+    public Request connectTimeout(final Timeout timeout) {
         this.connectTimeout = timeout;
         return this;
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Response.java
----------------------------------------------------------------------
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Response.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Response.java
index 06a4f47..2cd74fa 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Response.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Response.java
@@ -39,7 +39,7 @@ import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 
@@ -83,10 +83,9 @@ public class Response {
     }
 
     /**
-     * Handles the response using the specified {@link ResponseHandler}
+     * Handles the response using the specified {@link HttpClientResponseHandler}
      */
-    public <T> T handleResponse(
-            final ResponseHandler<T> handler) throws IOException {
+    public <T> T handleResponse(final HttpClientResponseHandler<T> handler) throws IOException {
         assertNotConsumed();
         try {
             return handler.handleResponse(this.response);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AbstractSimpleServerExchangeHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AbstractSimpleServerExchangeHandler.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AbstractSimpleServerExchangeHandler.java
index cf3a8ef..5200e63 100644
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AbstractSimpleServerExchangeHandler.java
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AbstractSimpleServerExchangeHandler.java
@@ -34,12 +34,12 @@ import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
+import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.BasicResponseProducer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.AbstractAsyncRequesterConsumer;
 import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
-import org.apache.hc.core5.http.nio.support.BasicAsyncResponseProducer;
-import org.apache.hc.core5.http.nio.support.ResponseTrigger;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 
@@ -67,10 +67,10 @@ public abstract class AbstractSimpleServerExchangeHandler extends AbstractServer
     @Override
     protected final void handle(
             final SimpleHttpRequest request,
-            final ResponseTrigger responseTrigger,
+            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
             final HttpContext context) throws HttpException, IOException {
         final SimpleHttpResponse response = handle(request, HttpCoreContext.adapt(context));
-        responseTrigger.submitResponse(new BasicAsyncResponseProducer(
+        responseTrigger.submitResponse(new BasicResponseProducer(
                 response,
                 response.getBody() != null ? new StringAsyncEntityProducer(response.getBody(), response.getContentType()) : null));
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java
index eb74c53..03bc189 100644
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncEchoHandler.java
@@ -48,6 +48,7 @@ import org.apache.hc.core5.http.nio.DataStreamChannel;
 import org.apache.hc.core5.http.nio.ResponseChannel;
 import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.util.Asserts;
 
 /**
@@ -76,7 +77,8 @@ public class AsyncEchoHandler implements AsyncServerExchangeHandler {
     public void handleRequest(
             final HttpRequest request,
             final EntityDetails entityDetails,
-            final ResponseChannel responseChannel) throws HttpException, IOException {
+            final ResponseChannel responseChannel,
+            final HttpContext context) throws HttpException, IOException {
         final String method = request.getMethod();
         if (!"GET".equalsIgnoreCase(method) &&
                 !"HEAD".equalsIgnoreCase(method) &&

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncRandomHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncRandomHandler.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncRandomHandler.java
index f7d9bc6..9e44db3 100644
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncRandomHandler.java
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AsyncRandomHandler.java
@@ -52,6 +52,7 @@ import org.apache.hc.core5.http.nio.DataStreamChannel;
 import org.apache.hc.core5.http.nio.ResponseChannel;
 import org.apache.hc.core5.http.nio.StreamChannel;
 import org.apache.hc.core5.http.nio.entity.AbstractBinAsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.util.Asserts;
 
 /**
@@ -77,7 +78,8 @@ public class AsyncRandomHandler implements AsyncServerExchangeHandler {
     public void handleRequest(
             final HttpRequest request,
             final EntityDetails entityDetails,
-            final ResponseChannel responseChannel) throws HttpException, IOException {
+            final ResponseChannel responseChannel,
+            final HttpContext context) throws HttpException, IOException {
         final String method = request.getMethod();
         if (!"GET".equalsIgnoreCase(method) &&
                 !"HEAD".equalsIgnoreCase(method) &&

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AuthenticatingAsyncDecorator.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AuthenticatingAsyncDecorator.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AuthenticatingAsyncDecorator.java
new file mode 100644
index 0000000..d9cd69c
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/AuthenticatingAsyncDecorator.java
@@ -0,0 +1,181 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.testing.async;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.hc.client5.testing.auth.Authenticator;
+import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncResponseProducer;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.BasicResponseProducer;
+import org.apache.hc.core5.http.nio.CapacityChannel;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.net.URIAuthority;
+import org.apache.hc.core5.util.Args;
+
+public class AuthenticatingAsyncDecorator implements AsyncServerExchangeHandler {
+
+    private final AsyncServerExchangeHandler exchangeHandler;
+    private final Authenticator authenticator;
+    private final AtomicReference<AsyncResponseProducer> responseProducerRef;
+    private final BasicAuthTokenExtractor authTokenExtractor;
+
+    public AuthenticatingAsyncDecorator(final AsyncServerExchangeHandler exchangeHandler, final Authenticator authenticator) {
+        this.exchangeHandler = Args.notNull(exchangeHandler, "Request handler");
+        this.authenticator = Args.notNull(authenticator, "Authenticator");
+        this.responseProducerRef = new AtomicReference<>(null);
+        this.authTokenExtractor = new BasicAuthTokenExtractor();
+    }
+
+    protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+    }
+
+    @Override
+    public void handleRequest(
+            final HttpRequest request,
+            final EntityDetails entityDetails,
+            final ResponseChannel responseChannel,
+            final HttpContext context) throws HttpException, IOException {
+        final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
+        final String challengeResponse = h != null ? authTokenExtractor.extract(h.getValue()) : null;
+
+        final URIAuthority authority = request.getAuthority();
+        final String requestUri = request.getRequestUri();
+
+        final boolean authenticated = authenticator.authenticate(authority, requestUri, challengeResponse);
+        final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
+        final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
+
+        if (authenticated) {
+            if (expectContinue) {
+                responseChannel.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
+            }
+            exchangeHandler.handleRequest(request, entityDetails, responseChannel, context);
+        } else {
+            final HttpResponse unauthorized = new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
+            final String realm = authenticator.getRealm(authority, requestUri);
+            unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
+
+            customizeUnauthorizedResponse(unauthorized);
+
+            final AsyncResponseProducer responseProducer = new BasicResponseProducer(
+                    unauthorized,
+                    new BasicAsyncEntityProducer("Unauthorized", ContentType.TEXT_PLAIN));
+            responseProducerRef.set(responseProducer);
+            responseProducer.sendResponse(responseChannel);
+        }
+
+    }
+
+    @Override
+    public final void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+        final AsyncResponseProducer responseProducer = responseProducerRef.get();
+        if (responseProducer == null) {
+            exchangeHandler.updateCapacity(capacityChannel);
+        } else {
+            capacityChannel.update(Integer.MAX_VALUE);
+        }
+    }
+
+    @Override
+    public final int consume(final ByteBuffer src) throws IOException {
+        final AsyncResponseProducer responseProducer = responseProducerRef.get();
+        if (responseProducer == null) {
+            return exchangeHandler.consume(src);
+        } else {
+            return Integer.MAX_VALUE;
+        }
+    }
+
+    @Override
+    public final void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+        final AsyncResponseProducer responseProducer = responseProducerRef.get();
+        if (responseProducer == null) {
+            exchangeHandler.streamEnd(trailers);
+        }
+    }
+
+    @Override
+    public final int available() {
+        final AsyncResponseProducer responseProducer = responseProducerRef.get();
+        if (responseProducer == null) {
+            return exchangeHandler.available();
+        } else {
+            return responseProducer.available();
+        }
+    }
+
+    @Override
+    public final void produce(final DataStreamChannel channel) throws IOException {
+        final AsyncResponseProducer responseProducer = responseProducerRef.get();
+        if (responseProducer == null) {
+            exchangeHandler.produce(channel);
+        } else {
+            responseProducer.produce(channel);
+        }
+    }
+
+    @Override
+    public final void failed(final Exception cause) {
+        try {
+            exchangeHandler.failed(cause);
+            final AsyncResponseProducer dataProducer = responseProducerRef.getAndSet(null);
+            if (dataProducer != null) {
+                dataProducer.failed(cause);
+            }
+        } finally {
+            releaseResources();
+        }
+    }
+
+    @Override
+    public final void releaseResources() {
+        exchangeHandler.releaseResources();
+        final AsyncResponseProducer dataProducer = responseProducerRef.getAndSet(null);
+        if (dataProducer != null) {
+            dataProducer.releaseResources();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/Authenticator.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/Authenticator.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/Authenticator.java
new file mode 100644
index 0000000..911b3c4
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/Authenticator.java
@@ -0,0 +1,38 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.testing.auth;
+
+import org.apache.hc.core5.net.URIAuthority;
+
+public interface Authenticator {
+
+    boolean authenticate(URIAuthority authority, String requestUri, String credentials);
+
+    String getRealm(URIAuthority authority, String requestUri);
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/BasicAuthTokenExtractor.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/BasicAuthTokenExtractor.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/BasicAuthTokenExtractor.java
index a29778f..5c5abfb 100644
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/BasicAuthTokenExtractor.java
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/BasicAuthTokenExtractor.java
@@ -32,43 +32,30 @@ import java.nio.charset.StandardCharsets;
 import org.apache.commons.codec.BinaryDecoder;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.ProtocolException;
 
 public class BasicAuthTokenExtractor {
 
-    public String extract(final HttpRequest request) throws HttpException {
-        String auth = null;
-
-        final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
-        if (h != null) {
-            final String s = h.getValue();
-            if (s != null) {
-                auth = s.trim();
-            }
-        }
-
-        if (auth != null) {
-            final int i = auth.indexOf(' ');
+    public String extract(final String challengeResponse) throws HttpException {
+        if (challengeResponse != null) {
+            final int i = challengeResponse.indexOf(' ');
             if (i == -1) {
-                throw new ProtocolException("Invalid Authorization header: " + auth);
+                throw new ProtocolException("Invalid challenge response: " + challengeResponse);
             }
-            final String authscheme = auth.substring(0, i);
+            final String authscheme = challengeResponse.substring(0, i);
             if (authscheme.equalsIgnoreCase("basic")) {
-                final String s = auth.substring(i + 1).trim();
+                final String s = challengeResponse.substring(i + 1).trim();
                 try {
                     final byte[] credsRaw = s.getBytes(StandardCharsets.US_ASCII);
                     final BinaryDecoder codec = new Base64();
-                    auth = new String(codec.decode(credsRaw), StandardCharsets.US_ASCII);
+                    return new String(codec.decode(credsRaw), StandardCharsets.US_ASCII);
                 } catch (final DecoderException ex) {
                     throw new ProtocolException("Malformed BASIC credentials");
                 }
             }
         }
-        return auth;
+        return null;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/RequestBasicAuth.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/RequestBasicAuth.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/RequestBasicAuth.java
deleted file mode 100644
index 5832b6d..0000000
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/RequestBasicAuth.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.testing.auth;
-
-import java.io.IOException;
-
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpRequestInterceptor;
-import org.apache.hc.core5.http.protocol.HttpContext;
-
-public class RequestBasicAuth implements HttpRequestInterceptor {
-
-    private final BasicAuthTokenExtractor authTokenExtractor;
-
-    public RequestBasicAuth() {
-        super();
-        this.authTokenExtractor = new BasicAuthTokenExtractor();
-    }
-
-    @Override
-    public void process(
-            final HttpRequest request,
-            final EntityDetails entityDetails,
-            final HttpContext context) throws HttpException, IOException {
-        context.setAttribute("creds", this.authTokenExtractor.extract(request));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/ResponseBasicUnauthorized.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/ResponseBasicUnauthorized.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/ResponseBasicUnauthorized.java
deleted file mode 100644
index cce7525..0000000
--- a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/auth/ResponseBasicUnauthorized.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.testing.auth;
-
-import java.io.IOException;
-
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpResponseInterceptor;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.protocol.HttpContext;
-
-public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
-
-    @Override
-    public void process(
-            final HttpResponse response,
-            final EntityDetails entityDetails,
-            final HttpContext context) throws HttpException, IOException {
-        if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
-            if (!response.containsHeader(HttpHeaders.WWW_AUTHENTICATE)) {
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/AuthenticatingDecorator.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/AuthenticatingDecorator.java b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/AuthenticatingDecorator.java
new file mode 100644
index 0000000..ddfa52c
--- /dev/null
+++ b/httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/AuthenticatingDecorator.java
@@ -0,0 +1,105 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.testing.classic;
+
+import java.io.IOException;
+
+import org.apache.hc.client5.testing.auth.Authenticator;
+import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.net.URIAuthority;
+import org.apache.hc.core5.util.Args;
+
+public class AuthenticatingDecorator implements HttpServerRequestHandler {
+
+    private final HttpServerRequestHandler requestHandler;
+    private final Authenticator authenticator;
+    private final BasicAuthTokenExtractor authTokenExtractor;
+
+    public AuthenticatingDecorator(final HttpServerRequestHandler requestHandler, final Authenticator authenticator) {
+        this.requestHandler = Args.notNull(requestHandler, "Request handler");
+        this.authenticator = Args.notNull(authenticator, "Authenticator");
+        this.authTokenExtractor = new BasicAuthTokenExtractor();
+    }
+
+    protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+    }
+
+    @Override
+    public void handle(
+            final ClassicHttpRequest request,
+            final ResponseTrigger responseTrigger,
+            final HttpContext context) throws HttpException, IOException {
+        final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
+        final String challengeResponse = h != null ? authTokenExtractor.extract(h.getValue()) : null;
+
+        final URIAuthority authority = request.getAuthority();
+        final String requestUri = request.getRequestUri();
+
+        final boolean authenticated = authenticator.authenticate(authority, requestUri, challengeResponse);
+        final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
+        final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
+
+        if (authenticated) {
+            if (expectContinue) {
+                responseTrigger.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
+            }
+            requestHandler.handle(request, responseTrigger, context);
+        } else {
+            final ClassicHttpResponse unauthorized = new BasicClassicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
+            final String realm = authenticator.getRealm(authority, requestUri);
+            unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\"");
+            customizeUnauthorizedResponse(unauthorized);
+            if (unauthorized.getEntity() == null) {
+                unauthorized.setEntity(new StringEntity("Unauthorized"));
+            }
+            if (expectContinue || request.getEntity() == null) {
+                // Respond immediately
+                responseTrigger.submitResponse(unauthorized);
+                // Consume request body later
+                EntityUtils.consume(request.getEntity());
+            } else {
+                // Consume request body first
+                EntityUtils.consume(request.getEntity());
+                // Respond later
+                responseTrigger.submitResponse(unauthorized);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/BasicTestAuthenticator.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/BasicTestAuthenticator.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/BasicTestAuthenticator.java
new file mode 100644
index 0000000..933071e
--- /dev/null
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/BasicTestAuthenticator.java
@@ -0,0 +1,54 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.testing;
+
+import java.util.Objects;
+
+import org.apache.hc.client5.testing.auth.Authenticator;
+import org.apache.hc.core5.net.URIAuthority;
+
+public class BasicTestAuthenticator implements Authenticator {
+
+    private final String userToken;
+    private final String realm;
+
+    public BasicTestAuthenticator(final String userToken, final String realm) {
+        this.userToken = userToken;
+        this.realm = realm;
+    }
+
+    public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
+        return Objects.equals(userToken, credentials);
+    }
+
+    @Override
+    public String getRealm(final URIAuthority authority, final String requestUri) {
+        return realm;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/IntegrationTestBase.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/IntegrationTestBase.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/IntegrationTestBase.java
index 262eb82..4ba9ce1 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/IntegrationTestBase.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/IntegrationTestBase.java
@@ -28,13 +28,16 @@
 package org.apache.hc.client5.testing.async;
 
 import java.net.InetSocketAddress;
+import java.util.concurrent.Future;
 
 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
+import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.impl.HttpProcessors;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
@@ -72,16 +75,25 @@ public abstract class IntegrationTestBase extends LocalAsyncServerTestBase {
 
     };
 
-    public HttpHost start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
-        server.start(httpProcessor, h1Config);
-        final ListenerEndpoint listener = server.listen(new InetSocketAddress(0));
+    public HttpHost start(
+            final HttpProcessor httpProcessor,
+            final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
+            final H1Config h1Config) throws Exception {
+        server.start(httpProcessor, exchangeHandlerDecorator, h1Config);
+        final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
         httpclient = clientBuilder.build();
         httpclient.start();
-        listener.waitFor();
-        final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
+        final ListenerEndpoint endpoint = endpointFuture.get();
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
         return new HttpHost("localhost", address.getPort(), scheme.name());
     }
 
+    public HttpHost start(
+            final HttpProcessor httpProcessor,
+            final H1Config h1Config) throws Exception {
+        return start(httpProcessor, null, h1Config);
+    }
+
     public HttpHost start() throws Exception {
         return start(HttpProcessors.server(), H1Config.DEFAULT);
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncRedirects.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncRedirects.java
index 27866ba..9bfc3b2 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncRedirects.java
@@ -763,8 +763,8 @@ public class TestAsyncRedirects extends IntegrationTestBase {
             });
 
             secondServer.start();
-            final ListenerEndpoint endpoint2 = secondServer.listen(new InetSocketAddress(0));
-            endpoint2.waitFor();
+            final Future<ListenerEndpoint> endpointFuture = secondServer.listen(new InetSocketAddress(0));
+            final ListenerEndpoint endpoint2 = endpointFuture.get();
 
             final InetSocketAddress address2 = (InetSocketAddress) endpoint2.getAddress();
             final HttpHost initialTarget = new HttpHost("localhost", address2.getPort(), scheme.name());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestClientAuthentication.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestClientAuthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestClientAuthentication.java
index a1d2588..44eb1be 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestClientAuthentication.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestClientAuthentication.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.testing.async;
 
-import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -52,18 +51,16 @@ import org.apache.hc.client5.http.impl.protocol.DefaultAuthenticationStrategy;
 import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.client5.testing.auth.RequestBasicAuth;
-import org.apache.hc.client5.testing.auth.ResponseBasicUnauthorized;
+import org.apache.hc.client5.testing.BasicTestAuthenticator;
+import org.apache.hc.client5.testing.auth.Authenticator;
+import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.HeaderElements;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.H1Config;
@@ -71,13 +68,10 @@ import org.apache.hc.core5.http.config.Registry;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.HttpProcessors;
 import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.message.BasicHttpResponse;
-import org.apache.hc.core5.http.nio.AsyncResponseProducer;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
-import org.apache.hc.core5.http.nio.support.BasicAsyncResponseProducer;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.net.URIAuthority;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -100,41 +94,17 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
     @Override
     public HttpHost start() throws Exception {
-        return super.start(HttpProcessors.customServer(null)
-                .add(new RequestBasicAuth())
-                .add(new ResponseBasicUnauthorized())
-                .build(),
-                H1Config.DEFAULT);
-    }
-
-    static class AuthHandler extends AbstractSimpleServerExchangeHandler {
-
-        private final boolean keepAlive;
-
-        AuthHandler(final boolean keepAlive) {
-            super();
-            this.keepAlive = keepAlive;
-        }
-
-        AuthHandler() {
-            this(true);
-        }
+        return super.start(
+                HttpProcessors.server(),
+                new Decorator<AsyncServerExchangeHandler>() {
 
-        @Override
-        protected SimpleHttpResponse handle(
-                final SimpleHttpRequest request,
-                final HttpCoreContext context) throws HttpException {
-            final String creds = (String) context.getAttribute("creds");
-            final SimpleHttpResponse response;
-            if (creds == null || !creds.equals("test:test")) {
-                response = new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response = new SimpleHttpResponse(HttpStatus.SC_OK, "success", ContentType.TEXT_PLAIN);
-            }
-            response.setHeader(HttpHeaders.CONNECTION, this.keepAlive ? HeaderElements.KEEP_ALIVE : HeaderElements.CLOSE);
-            return response;
-        }
+                    @Override
+                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler requestHandler) {
+                        return new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm"));
+                    }
 
+                },
+                H1Config.DEFAULT);
     }
 
     static class TestCredentialsProvider implements CredentialsStore {
@@ -173,7 +143,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -199,7 +169,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -226,7 +196,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -253,11 +223,27 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler(false);
+                return new AsyncEchoHandler();
             }
 
         });
-        final HttpHost target = start();
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<AsyncServerExchangeHandler>() {
+
+                    @Override
+                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+                        return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
+
+                            @Override
+                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                                unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                            }
+                        };
+                    }
+
+                },
+                H1Config.DEFAULT);
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
                 new UsernamePasswordCredentials("test", "test".toCharArray()));
@@ -280,23 +266,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler() {
-
-                    @Override
-                    protected AsyncResponseProducer verify(
-                            final HttpRequest request,
-                            final HttpContext context) throws IOException, HttpException {
-
-                        final String creds = (String) context.getAttribute("creds");
-                        if (creds == null || !creds.equals("test:test")) {
-                            return new BasicAsyncResponseProducer(new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED),
-                                    new StringAsyncEntityProducer("Unauthorized"));
-                        } else {
-                            return null;
-                        }
-                    }
-
-                };
+                return new AsyncEchoHandler();
             }
 
         });
@@ -321,23 +291,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler() {
-
-                    @Override
-                    protected AsyncResponseProducer verify(
-                            final HttpRequest request,
-                            final HttpContext context) throws IOException, HttpException {
-
-                        final String creds = (String) context.getAttribute("creds");
-                        if (creds == null || !creds.equals("test:test")) {
-                            return new BasicAsyncResponseProducer(new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED),
-                                    new StringAsyncEntityProducer("Unauthorized"));
-                        } else {
-                            return null;
-                        }
-                    }
-
-                };
+                return new AsyncEchoHandler();
             }
 
         });
@@ -365,7 +319,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -409,7 +363,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -422,7 +376,6 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
-        Assert.assertEquals("success", response.getBody());
     }
 
     @Test
@@ -431,7 +384,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -452,7 +405,7 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
@@ -482,42 +435,18 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
-        Assert.assertEquals("success", response.getBody());
     }
 
     @Test
     public void testReauthentication() throws Exception {
-        final AtomicLong count = new AtomicLong(0);
-
         server.register("*", new Supplier<AsyncServerExchangeHandler>() {
 
             @Override
             public AsyncServerExchangeHandler get() {
-
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(
-                            final SimpleHttpRequest request,
-                            final HttpCoreContext context) throws HttpException {
-                        final String creds = (String) context.getAttribute("creds");
-                        if (creds == null || !creds.equals("test:test")) {
-                            return new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
-                        } else {
-                            // Make client re-authenticate on each fourth request
-                            if (count.incrementAndGet() % 4 == 0) {
-                                return new SimpleHttpResponse(HttpStatus.SC_UNAUTHORIZED);
-                            } else {
-                                return new SimpleHttpResponse(HttpStatus.SC_OK, "success", ContentType.TEXT_PLAIN);
-                            }
-                        }
-                    }
-
-                };
+                return new AsyncEchoHandler();
             }
 
         });
-
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
                 new UsernamePasswordCredentials("test", "test".toCharArray()));
 
@@ -540,23 +469,43 @@ public class TestClientAuthentication extends IntegrationTestBase {
                 .build();
         this.clientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
 
-        final HttpHost target = start(HttpProcessors.customServer(null)
-                        .add(new RequestBasicAuth())
-                        .add(new HttpResponseInterceptor() {
+        final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
+
+            private final AtomicLong count = new AtomicLong(0);
+
+            @Override
+            public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
+                final boolean authenticated = super.authenticate(authority, requestUri, credentials);
+                if (authenticated) {
+                    if (this.count.incrementAndGet() % 4 != 0) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    return false;
+                }
+            }
+        };
+
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<AsyncServerExchangeHandler>() {
+
+                    @Override
+                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+                        return new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
 
                             @Override
-                            public void process(
-                                    final HttpResponse response,
-                                    final EntityDetails entityDetails,
-                                    final HttpContext context) throws HttpException, IOException {
-                                if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
-                                    response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
-                                }
+                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                                unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
+                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
                             }
 
-                        })
-                        .build(),
-                H1Config.DEFAULT);
+                        };
+                    }
+
+                }, H1Config.DEFAULT);
 
         final RequestConfig config = RequestConfig.custom()
                 .setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
@@ -583,31 +532,27 @@ public class TestClientAuthentication extends IntegrationTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-
-                return new AuthHandler();
+                return new AsyncEchoHandler();
             }
 
         });
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<AsyncServerExchangeHandler>() {
 
-        final HttpHost target = start(HttpProcessors.customServer(null)
-                        .add(new RequestBasicAuth())
-                        .add(new HttpResponseInterceptor() {
+                    @Override
+                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
+                        return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
                             @Override
-                            public void process(
-                                    final HttpResponse response,
-                                    final EntityDetails entityDetails,
-                                    final HttpContext context) throws HttpException, IOException {
-                                if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
-                                    response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
-                                    response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
-                                }
+                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
                             }
 
-                        })
-                        .build(),
-                H1Config.DEFAULT);
+                        };
+                    }
 
+                }, H1Config.DEFAULT);
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
                 new UsernamePasswordCredentials("test", "test".toCharArray()));
@@ -618,7 +563,6 @@ public class TestClientAuthentication extends IntegrationTestBase {
         final SimpleHttpResponse response = future.get();
         Assert.assertNotNull(response);
         Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
-        Assert.assertEquals("success", response.getBody());
         final AuthScope authscope = credsProvider.getAuthScope();
         Assert.assertNotNull(authscope);
         Assert.assertEquals("test realm", authscope.getRealm());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
index e5275cd..5ae7fe7 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
@@ -168,10 +168,10 @@ public class TestHttpAsyncMinimal {
         } else {
             server.start(H1Config.DEFAULT);
         }
-        final ListenerEndpoint listener = server.listen(new InetSocketAddress(0));
+        final Future<ListenerEndpoint> endpointFuture = server.listen(new InetSocketAddress(0));
         httpclient.start();
-        listener.waitFor();
-        final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
+        final ListenerEndpoint endpoint = endpointFuture.get();
+        final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
         return new HttpHost("localhost", address.getPort(), scheme.name());
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
index a5e6f29..a5df79c 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
@@ -41,8 +41,8 @@ import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.ResponseHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.protocol.HttpContext;
@@ -52,10 +52,9 @@ import org.junit.Test;
 
 public class TestFluent extends LocalServerTestBase {
 
-    @Before @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        this.serverBootstrap.registerHandler("/", new HttpRequestHandler() {
+        this.server.registerHandler("/", new HttpRequestHandler() {
 
             @Override
             public void handle(
@@ -66,7 +65,7 @@ public class TestFluent extends LocalServerTestBase {
             }
 
         });
-        this.serverBootstrap.registerHandler("/echo", new HttpRequestHandler() {
+        this.server.registerHandler("/echo", new HttpRequestHandler() {
 
             @Override
             public void handle(
@@ -155,7 +154,7 @@ public class TestFluent extends LocalServerTestBase {
             Request.Get(baseURL + "/").execute().returnContent();
             Request.Get(baseURL + "/").execute().returnResponse();
             Request.Get(baseURL + "/").execute().discardContent();
-            Request.Get(baseURL + "/").execute().handleResponse(new ResponseHandler<Object>() {
+            Request.Get(baseURL + "/").execute().handleResponse(new HttpClientResponseHandler<Object>() {
 
                 @Override
                 public Object handleResponse(

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java
index 3f710db..85f8ab2 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java
@@ -27,35 +27,31 @@
 
 package org.apache.hc.client5.testing.sync;
 
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
 import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
 import org.apache.hc.client5.testing.SSLTestContexts;
 import org.apache.hc.client5.testing.classic.EchoHandler;
 import org.apache.hc.client5.testing.classic.RandomHandler;
+import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.SocketConfig;
-import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
-import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.io.ShutdownType;
-import org.apache.hc.core5.util.TimeValue;
-import org.junit.After;
-import org.junit.Before;
+import org.apache.hc.core5.testing.classic.ClassicTestServer;
+import org.junit.Rule;
+import org.junit.rules.ExternalResource;
 
 /**
  * Base class for tests using local test server. The server will not be started per default.
  */
 public abstract class LocalServerTestBase {
 
-    protected final URIScheme scheme;
-
-    protected ServerBootstrap serverBootstrap;
-    protected HttpServer server;
-    protected PoolingHttpClientConnectionManager connManager;
-    protected HttpClientBuilder clientBuilder;
-    protected CloseableHttpClient httpclient;
-
     public LocalServerTestBase(final URIScheme scheme) {
         this.scheme = scheme;
     }
@@ -64,48 +60,81 @@ public abstract class LocalServerTestBase {
         this(URIScheme.HTTP);
     }
 
-    public String getSchemeName() {
-        return this.scheme.name();
-    }
+    protected final URIScheme scheme;
+
+    protected ClassicTestServer server;
 
-    @Before
-    public void setUp() throws Exception {
-        final SocketConfig socketConfig = SocketConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(15))
-                .build();
-        this.serverBootstrap = ServerBootstrap.bootstrap()
-                .setSocketConfig(socketConfig)
-                .registerHandler("/echo/*", new EchoHandler())
-                .registerHandler("/random/*", new RandomHandler());
-        if (this.scheme.equals(URIScheme.HTTPS)) {
-            this.serverBootstrap.setSslContext(SSLTestContexts.createServerSSLContext());
+    @Rule
+    public ExternalResource serverResource = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            server = new ClassicTestServer(
+                    scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
+                    SocketConfig.custom()
+                            .setSoTimeout(5, TimeUnit.SECONDS)
+                            .build());
+            server.registerHandler("/echo/*", new EchoHandler());
+            server.registerHandler("/random/*", new RandomHandler());
         }
 
-        this.connManager = new PoolingHttpClientConnectionManager();
-        this.connManager.setDefaultSocketConfig(socketConfig);
-        this.clientBuilder = HttpClientBuilder.create()
-                .setConnectionManager(this.connManager);
-    }
+        @Override
+        protected void after() {
+            if (server != null) {
+                try {
+                    server.shutdown(ShutdownType.IMMEDIATE);
+                    server = null;
+                } catch (final Exception ignore) {
+                }
+            }
+        }
 
-    @After
-    public void shutDown() throws Exception {
-        if (this.httpclient != null) {
-            this.httpclient.close();
+    };
+
+    protected PoolingHttpClientConnectionManager connManager;
+    protected HttpClientBuilder clientBuilder;
+    protected CloseableHttpClient httpclient;
+
+    @Rule
+    public ExternalResource clientResource = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            connManager = new PoolingHttpClientConnectionManager();
+            connManager.setDefaultSocketConfig(SocketConfig.custom()
+                    .setSoTimeout(5, TimeUnit.SECONDS)
+                    .build());
+            clientBuilder = HttpClientBuilder.create()
+                    .setConnectionManager(connManager);
         }
-        if (this.server != null) {
-            this.server.shutdown(ShutdownType.IMMEDIATE);
+
+        @Override
+        protected void after() {
+            if (httpclient != null) {
+                try {
+                    httpclient.close();
+                    httpclient = null;
+                } catch (final Exception ignore) {
+                }
+            }
         }
-    }
 
-    public HttpHost start() throws Exception {
-        this.server = this.serverBootstrap.create();
-        this.server.start();
+    };
+
+    public HttpHost start(
+            final HttpProcessor httpProcessor,
+            final Decorator<HttpServerRequestHandler> handlerDecorator) throws IOException {
+        this.server.start(httpProcessor, handlerDecorator);
 
         if (this.httpclient == null) {
             this.httpclient = this.clientBuilder.build();
         }
 
-        return new HttpHost("localhost", this.server.getLocalPort(), this.scheme.name());
+        return new HttpHost("localhost", this.server.getPort(), this.scheme.name());
+    }
+
+    public HttpHost start() throws Exception {
+        return start(null, null);
     }
 
 }


[3/6] httpcomponents-client git commit: Upgraded HttpCore to version 5.0-alpha4

Posted by ol...@apache.org.
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
index 6a1e999..bd61075 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
@@ -53,7 +53,6 @@ import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.UriHttpRequestHandlerMapper;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicHeader;
@@ -120,15 +119,20 @@ public class TestRedirects extends LocalServerTestBase {
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final String uri = request.getRequestUri();
-            if (uri.startsWith("/circular-oldlocation")) {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", "/circular-location2"));
-            } else if (uri.startsWith("/circular-location2")) {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
-            } else {
-                response.setCode(HttpStatus.SC_NOT_FOUND);
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.startsWith("/circular-oldlocation")) {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", "/circular-location2"));
+                } else if (path.startsWith("/circular-location2")) {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", "/circular-oldlocation"));
+                } else {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                }
+            } catch (final URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
     }
@@ -144,16 +148,21 @@ public class TestRedirects extends LocalServerTestBase {
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final String uri = request.getRequestUri();
-            if (uri.equals("/oldlocation/")) {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", "/relativelocation/"));
-            } else if (uri.equals("/relativelocation/")) {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("Successful redirect");
-                response.setEntity(entity);
-            } else {
-                response.setCode(HttpStatus.SC_NOT_FOUND);
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.equals("/oldlocation/")) {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", "/relativelocation/"));
+                } else if (path.equals("/relativelocation/")) {
+                    response.setCode(HttpStatus.SC_OK);
+                    final StringEntity entity = new StringEntity("Successful redirect");
+                    response.setEntity(entity);
+                } else {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                }
+            } catch (final URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
     }
@@ -169,16 +178,21 @@ public class TestRedirects extends LocalServerTestBase {
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final String uri = request.getRequestUri();
-            if (uri.equals("/test/oldlocation")) {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", "relativelocation"));
-            } else if (uri.equals("/test/relativelocation")) {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("Successful redirect");
-                response.setEntity(entity);
-            } else {
-                response.setCode(HttpStatus.SC_NOT_FOUND);
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.equals("/test/oldlocation")) {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", "relativelocation"));
+                } else if (path.equals("/test/relativelocation")) {
+                    response.setCode(HttpStatus.SC_OK);
+                    final StringEntity entity = new StringEntity("Successful redirect");
+                    response.setEntity(entity);
+                } else {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                }
+            } catch (final URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
     }
@@ -194,24 +208,36 @@ public class TestRedirects extends LocalServerTestBase {
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final String uri = request.getRequestUri();
-            if (uri.equals("/rome")) {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("Successful redirect");
-                response.setEntity(entity);
-            } else {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", "/rome"));
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.equals("/rome")) {
+                    response.setCode(HttpStatus.SC_OK);
+                    final StringEntity entity = new StringEntity("Successful redirect");
+                    response.setEntity(entity);
+                } else {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", "/rome"));
+                }
+            } catch (final URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
     }
 
-    private static class BogusRedirectService implements HttpRequestHandler {
-        private final String url;
+    interface UriTransformation {
+
+        String rewrite(URI requestUri);
 
-        public BogusRedirectService(final String redirectUrl) {
+    }
+
+    private static class TransformingRedirectService implements HttpRequestHandler {
+
+        private final UriTransformation uriTransformation;
+
+        public TransformingRedirectService(final UriTransformation uriTransformation) {
             super();
-            this.url = redirectUrl;
+            this.uriTransformation = uriTransformation;
         }
 
         @Override
@@ -219,24 +245,28 @@ public class TestRedirects extends LocalServerTestBase {
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final String uri = request.getRequestUri();
-            if (uri.equals("/oldlocation/")) {
-                response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
-                response.addHeader(new BasicHeader("Location", url));
-            } else if (uri.equals("/relativelocation/")) {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("Successful redirect");
-                response.setEntity(entity);
-            } else {
-                response.setCode(HttpStatus.SC_NOT_FOUND);
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.equals("/oldlocation/")) {
+                    response.setCode(HttpStatus.SC_MOVED_TEMPORARILY);
+                    response.addHeader(new BasicHeader("Location", uriTransformation.rewrite(requestURI)));
+                } else if (path.equals("/relativelocation/")) {
+                    response.setCode(HttpStatus.SC_OK);
+                    final StringEntity entity = new StringEntity("Successful redirect");
+                    response.setEntity(entity);
+                } else {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                }
+            } catch (final URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
     }
 
     @Test
     public void testBasicRedirect300() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MULTIPLE_CHOICES));
 
         final HttpHost target = start();
 
@@ -258,8 +288,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect301() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_PERMANENTLY));
 
         final HttpHost target = start();
 
@@ -285,8 +314,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect302() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_MOVED_TEMPORARILY));
 
         final HttpHost target = start();
 
@@ -305,7 +333,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect302NoLocation() throws Exception {
-        this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", new HttpRequestHandler() {
 
             @Override
             public void handle(
@@ -334,8 +362,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect303() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
 
         final HttpHost target = start();
 
@@ -354,8 +381,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect304() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_NOT_MODIFIED));
 
         final HttpHost target = start();
 
@@ -374,8 +400,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect305() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_USE_PROXY));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_USE_PROXY));
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
@@ -393,8 +418,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect307() throws Exception {
-        this.serverBootstrap.registerHandler("*",
-                new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_TEMPORARY_REDIRECT));
 
         final HttpHost target = start();
 
@@ -413,7 +437,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testMaxRedirectCheck() throws Exception {
-        this.serverBootstrap.registerHandler("*", new CircularRedirectService());
+        this.server.registerHandler("*", new CircularRedirectService());
 
         final HttpHost target = start();
 
@@ -434,7 +458,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testCircularRedirect() throws Exception {
-        this.serverBootstrap.registerHandler("*", new CircularRedirectService());
+        this.server.registerHandler("*", new CircularRedirectService());
 
         final HttpHost target = start();
 
@@ -454,7 +478,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRepeatRequest() throws Exception {
-        this.serverBootstrap.registerHandler("*", new RomeRedirectService());
+        this.server.registerHandler("*", new RomeRedirectService());
 
         final HttpHost target = start();
 
@@ -477,7 +501,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRepeatRequestRedirect() throws Exception {
-        this.serverBootstrap.registerHandler("*", new RomeRedirectService());
+        this.server.registerHandler("*", new RomeRedirectService());
 
         final HttpHost target = start();
 
@@ -500,7 +524,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testDifferentRequestSameRedirect() throws Exception {
-        this.serverBootstrap.registerHandler("*", new RomeRedirectService());
+        this.server.registerHandler("*", new RomeRedirectService());
 
         final HttpHost target = start();
 
@@ -524,7 +548,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testPostRedirectSeeOther() throws Exception {
-        this.serverBootstrap.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
+        this.server.registerHandler("*", new BasicRedirectService(HttpStatus.SC_SEE_OTHER));
 
         final HttpHost target = start();
 
@@ -545,7 +569,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRelativeRedirect() throws Exception {
-        this.serverBootstrap.registerHandler("*", new RelativeRedirectService());
+        this.server.registerHandler("*", new RelativeRedirectService());
 
         final HttpHost target = start();
 
@@ -564,7 +588,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRelativeRedirect2() throws Exception {
-        this.serverBootstrap.registerHandler("*", new RelativeRedirectService2());
+        this.server.registerHandler("*", new RelativeRedirectService2());
 
         final HttpHost target = start();
 
@@ -583,7 +607,14 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testRejectBogusRedirectLocation() throws Exception {
-        this.serverBootstrap.registerHandler("*", new BogusRedirectService("xxx://bogus"));
+        this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
+
+            @Override
+            public String rewrite(final URI requestUri) {
+                return "xxx://bogus";
+            }
+
+        }));
 
         final HttpHost target = start();
 
@@ -600,14 +631,15 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testRejectInvalidRedirectLocation() throws Exception {
-        final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
-        this.serverBootstrap.setHandlerMapper(reqistry);
+        this.server.registerHandler("*", new TransformingRedirectService(new UriTransformation() {
 
-        final HttpHost target = start();
+            @Override
+            public String rewrite(final URI requestUri) {
+                return "/newlocation/?p=I have spaces";
+            }
 
-        reqistry.register("*",
-                new BogusRedirectService("http://" + target.toHostString() +
-                        "/newlocation/?p=I have spaces"));
+        }));
+        final HttpHost target = start();
 
         final HttpGet httpget = new HttpGet("/oldlocation/");
 
@@ -621,7 +653,7 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRedirectWithCookie() throws Exception {
-        this.serverBootstrap.registerHandler("*", new BasicRedirectService());
+        this.server.registerHandler("*", new BasicRedirectService());
 
         final HttpHost target = start();
 
@@ -653,7 +685,7 @@ public class TestRedirects extends LocalServerTestBase {
     public void testDefaultHeadersRedirect() throws Exception {
         this.clientBuilder.setDefaultHeaders(Arrays.asList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
 
-        this.serverBootstrap.registerHandler("*", new BasicRedirectService());
+        this.server.registerHandler("*", new BasicRedirectService());
 
         final HttpHost target = start();
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSPNegoScheme.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSPNegoScheme.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSPNegoScheme.java
index a9d8a2a..adea0f5 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSPNegoScheme.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSPNegoScheme.java
@@ -149,7 +149,7 @@ public class TestSPNegoScheme extends LocalServerTestBase {
      */
     @Test
     public void testDontTryToAuthenticateEndlessly() throws Exception {
-        this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
+        this.server.registerHandler("*", new PleaseNegotiateService());
         final HttpHost target = start();
 
         final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();
@@ -179,7 +179,7 @@ public class TestSPNegoScheme extends LocalServerTestBase {
      */
     @Test
     public void testNoTokenGeneratedError() throws Exception {
-        this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
+        this.server.registerHandler("*", new PleaseNegotiateService());
         final HttpHost target = start();
 
         final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
index 23ef3e9..73a36cc 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
@@ -75,7 +75,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
         final int workerCount = 5;
         final int requestCount = 5;
 
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         this.connManager.setMaxTotal(workerCount);
         this.connManager.setDefaultMaxPerRoute(workerCount);
@@ -194,7 +194,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
 
         final int maxConn = 2;
 
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         this.connManager.setMaxTotal(maxConn);
         this.connManager.setDefaultMaxPerRoute(maxConn);
@@ -229,7 +229,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
         // Send it to another route. Must be a keepalive.
         final HttpContext context2 = new BasicHttpContext();
         final ClassicHttpResponse response2 = this.httpclient.execute(
-                new HttpHost("127.0.0.1", this.server.getLocalPort()), new HttpGet("/"), context2);
+                new HttpHost("127.0.0.1", this.server.getPort()), new HttpGet("/"), context2);
         EntityUtils.consume(response2.getEntity());
         // ConnPoolByRoute now has 2 free connexions, out of its 2 max.
         // The [localhost][stuff] RouteSpcfcPool is the same as earlier

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
index b7a3502..a1079e5 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
@@ -48,9 +48,7 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.protocol.HttpContext;
-import org.junit.After;
 import org.junit.Assume;
-import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -58,10 +56,9 @@ import org.junit.Test;
  */
 public class TestWindowsNegotiateScheme extends LocalServerTestBase {
 
-    @Before @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        this.serverBootstrap.registerHandler("/", new HttpRequestHandler() {
+    @Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
+    public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
+        this.server.registerHandler("/", new HttpRequestHandler() {
 
             @Override
             public void handle(
@@ -73,15 +70,6 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
             }
 
         });
-    }
-
-    @After @Override
-    public void shutDown() throws Exception {
-        super.shutDown();
-    }
-
-    @Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
-    public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
         Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
 
         // HTTPCLIENT-1545

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java
index 6566afd..ca7bd01 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java
@@ -40,6 +40,7 @@ import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Example demonstrating how to evict expired and idle connections
@@ -50,7 +51,7 @@ public class AsyncClientConnectionEviction {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java
index a8bc323..efcb975 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java
@@ -42,7 +42,7 @@ import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates pipelined execution of multiple HTTP/1.1 message exchanges.
@@ -52,7 +52,7 @@ public class AsyncClientHttp1Pipelining {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H1Config.DEFAULT, ioReactorConfig);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java
index 370d745..ae0c239 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java
@@ -42,7 +42,7 @@ import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates concurrent (multiplexed) execution of multiple
@@ -53,7 +53,7 @@ public class AsyncClientHttp2Multiplexing {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H2Config.DEFAULT, ioReactorConfig);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2ServerPush.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2ServerPush.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2ServerPush.java
index 9d5ee4b..e7d7b42 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2ServerPush.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2ServerPush.java
@@ -48,7 +48,7 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates handling of HTTP/2 message exchanges pushed by the server.
@@ -58,7 +58,7 @@ public class AsyncClientHttp2ServerPush {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final H2Config h2Config = H2Config.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java
index ebe6ff0..000737d 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java
@@ -36,7 +36,7 @@ import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Example of asynchronous HTTP/1.1 request execution.
@@ -46,7 +46,7 @@ public class AsyncClientHttpExchange {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchangeStreaming.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchangeStreaming.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchangeStreaming.java
index 0c5ccca..8f531be 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchangeStreaming.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchangeStreaming.java
@@ -41,7 +41,7 @@ import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Example of asynchronous HTTP/1.1 request execution with response streaming.
@@ -51,7 +51,7 @@ public class AsyncClientHttpExchangeStreaming {
     public static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
index f591ae4..97297f2 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
@@ -57,7 +57,7 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates how to insert custom request interceptor and an execution interceptor
@@ -68,7 +68,7 @@ public class AsyncClientInterceptors {
     public final static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
index 8445b56..5b42d08 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
@@ -49,7 +49,7 @@ import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates how to use a custom execution interceptor
@@ -60,7 +60,7 @@ public class AsyncClientMessageTrailers {
     public final static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
-                .setSoTimeout(TimeValue.ofSeconds(5))
+                .setSoTimeout(Timeout.ofSeconds(5))
                 .build();
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientConfiguration.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientConfiguration.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientConfiguration.java
index cad7f3a..5fa54a9 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientConfiguration.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientConfiguration.java
@@ -81,6 +81,7 @@ import org.apache.hc.core5.http.message.LineParser;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.CharArrayBuffer;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * This example demonstrates how to customize and configure the most common aspects
@@ -208,9 +209,9 @@ public class ClientConfiguration {
             // Request configuration can be overridden at the request level.
             // They will take precedence over the one set at the client level.
             final RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
-                    .setSocketTimeout(TimeValue.ofSeconds(5))
-                    .setConnectTimeout(TimeValue.ofSeconds(5))
-                    .setConnectionRequestTimeout(TimeValue.ofSeconds(5))
+                    .setSocketTimeout(Timeout.ofSeconds(5))
+                    .setConnectTimeout(Timeout.ofSeconds(5))
+                    .setConnectionRequestTimeout(Timeout.ofSeconds(5))
                     .setProxy(new HttpHost("myotherproxy", 8080))
                     .build();
             httpget.setConfig(requestConfig);

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
index 541c55e..716af85 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
@@ -43,7 +43,7 @@ import org.apache.hc.client5.http.sync.methods.HttpGet;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 
 public class ClientWithRequestFuture {
 
@@ -59,8 +59,8 @@ public class ClientWithRequestFuture {
         final ExecutorService execService = Executors.newFixedThreadPool(5);
         try (FutureRequestExecutionService requestExecService = new FutureRequestExecutionService(
                 httpclient, execService)) {
-            // Because things are asynchronous, you must provide a ResponseHandler
-            final ResponseHandler<Boolean> handler = new ResponseHandler<Boolean>() {
+            // Because things are asynchronous, you must provide a HttpClientResponseHandler
+            final HttpClientResponseHandler<Boolean> handler = new HttpClientResponseHandler<Boolean>() {
                 @Override
                 public Boolean handleResponse(final ClassicHttpResponse response) throws IOException {
                     // simply return true if the status was OK

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
index f9166d2..38b9aa9 100644
--- a/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
+++ b/httpclient5/src/examples/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
@@ -37,11 +37,11 @@ import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.ParseException;
-import org.apache.hc.core5.http.io.ResponseHandler;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 
 /**
- * This example demonstrates the use of the {@link ResponseHandler} to simplify
+ * This example demonstrates the use of the {@link HttpClientResponseHandler} to simplify
  * the process of processing the HTTP response and releasing associated resources.
  */
 public class ClientWithResponseHandler {
@@ -53,7 +53,7 @@ public class ClientWithResponseHandler {
             System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
 
             // Create a custom response handler
-            final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
+            final HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>() {
 
                 @Override
                 public String handleResponse(

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java b/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java
index bd2958c..80f3458 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/config/RequestConfig.java
@@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  *  Immutable class encapsulating request configuration items.
@@ -42,9 +42,9 @@ import org.apache.hc.core5.util.TimeValue;
 @Contract(threading = ThreadingBehavior.IMMUTABLE)
 public class RequestConfig implements Cloneable {
 
-    private static final TimeValue DEFAULT_CONNECTION_REQUEST_TIMEOUT = TimeValue.ofMinutes(3);
-    private static final TimeValue DEFAULT_CONNECT_TIMEOUT = TimeValue.ofMinutes(3);
-    private static final TimeValue DEFAULT_SOCKET_TIMEOUT = TimeValue.NEG_ONE_MILLISECONDS;
+    private static final Timeout DEFAULT_CONNECTION_REQUEST_TIMEOUT = Timeout.ofMinutes(3);
+    private static final Timeout DEFAULT_CONNECT_TIMEOUT = Timeout.ofMinutes(3);
+    private static final Timeout DEFAULT_SOCKET_TIMEOUT = Timeout.ZERO_MILLISECONDS;
 
     public static final RequestConfig DEFAULT = new Builder().build();
 
@@ -58,9 +58,9 @@ public class RequestConfig implements Cloneable {
     private final boolean authenticationEnabled;
     private final Collection<String> targetPreferredAuthSchemes;
     private final Collection<String> proxyPreferredAuthSchemes;
-    private final TimeValue connectionRequestTimeout;
-    private final TimeValue connectTimeout;
-    private final TimeValue socketTimeout;
+    private final Timeout connectionRequestTimeout;
+    private final Timeout connectTimeout;
+    private final Timeout socketTimeout;
     private final boolean contentCompressionEnabled;
 
     /**
@@ -82,9 +82,9 @@ public class RequestConfig implements Cloneable {
             final boolean authenticationEnabled,
             final Collection<String> targetPreferredAuthSchemes,
             final Collection<String> proxyPreferredAuthSchemes,
-            final TimeValue connectionRequestTimeout,
-            final TimeValue connectTimeout,
-            final TimeValue socketTimeout,
+            final Timeout connectionRequestTimeout,
+            final Timeout connectTimeout,
+            final Timeout socketTimeout,
             final boolean contentCompressionEnabled) {
         super();
         this.expectContinueEnabled = expectContinueEnabled;
@@ -242,7 +242,7 @@ public class RequestConfig implements Cloneable {
      * Default: 3 minutes.
      * </p>
      */
-    public TimeValue getConnectionRequestTimeout() {
+    public Timeout getConnectionRequestTimeout() {
         return connectionRequestTimeout;
     }
 
@@ -257,7 +257,7 @@ public class RequestConfig implements Cloneable {
      * Default: 3 minutes
      * </p>
      */
-    public TimeValue getConnectTimeout() {
+    public Timeout getConnectTimeout() {
         return connectTimeout;
     }
 
@@ -273,7 +273,7 @@ public class RequestConfig implements Cloneable {
      * Default: no timeout.
      * </p>
      */
-    public TimeValue getSocketTimeout() {
+    public Timeout getSocketTimeout() {
         return socketTimeout;
     }
 
@@ -350,9 +350,9 @@ public class RequestConfig implements Cloneable {
         private boolean authenticationEnabled;
         private Collection<String> targetPreferredAuthSchemes;
         private Collection<String> proxyPreferredAuthSchemes;
-        private TimeValue connectionRequestTimeout;
-        private TimeValue connectTimeout;
-        private TimeValue socketTimeout;
+        private Timeout connectionRequestTimeout;
+        private Timeout connectTimeout;
+        private Timeout socketTimeout;
         private boolean contentCompressionEnabled;
 
         Builder() {
@@ -416,33 +416,33 @@ public class RequestConfig implements Cloneable {
             return this;
         }
 
-        public Builder setConnectionRequestTimeout(final TimeValue connectionRequestTimeout) {
+        public Builder setConnectionRequestTimeout(final Timeout connectionRequestTimeout) {
             this.connectionRequestTimeout = connectionRequestTimeout;
             return this;
         }
 
         public Builder setConnectionRequestTimeout(final long connectionRequestTimeout, final TimeUnit timeUnit) {
-            this.connectionRequestTimeout = TimeValue.of(connectionRequestTimeout, timeUnit);
+            this.connectionRequestTimeout = Timeout.of(connectionRequestTimeout, timeUnit);
             return this;
         }
 
-        public Builder setConnectTimeout(final TimeValue connectTimeout) {
+        public Builder setConnectTimeout(final Timeout connectTimeout) {
             this.connectTimeout = connectTimeout;
             return this;
         }
 
         public Builder setConnectTimeout(final long connectTimeout, final TimeUnit timeUnit) {
-            this.connectTimeout = TimeValue.of(connectTimeout, timeUnit);
+            this.connectTimeout = Timeout.of(connectTimeout, timeUnit);
             return this;
         }
 
-        public Builder setSocketTimeout(final TimeValue socketTimeout) {
+        public Builder setSocketTimeout(final Timeout socketTimeout) {
             this.socketTimeout = socketTimeout;
             return this;
         }
 
         public Builder setSocketTimeout(final long socketTimeout, final TimeUnit timeUnit) {
-            this.socketTimeout = TimeValue.of(socketTimeout, timeUnit);
+            this.socketTimeout = Timeout.of(socketTimeout, timeUnit);
             return this;
         }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/NamedElementChain.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/NamedElementChain.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/NamedElementChain.java
deleted file mode 100644
index 11cf854..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/NamedElementChain.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl;
-
-import org.apache.hc.core5.util.Args;
-
-/**
- * Chain of doubly linked elements.
- * <p>
- * This implementation makes no attempts to ensure uniqueness of element names.
- *
- * @param <E>
- */
-public class NamedElementChain<E> {
-
-    private final Node master;
-    private int size;
-
-    public NamedElementChain() {
-        this.master = new Node("master", null);
-        this.master.previous = this.master;
-        this.master.next = this.master;
-        this.size = 0;
-    }
-
-    public Node getFirst() {
-        if (master.next != master) {
-            return master.next;
-        } else {
-            return null;
-        }
-    }
-
-    public Node getLast() {
-        if (master.previous != master) {
-            return master.previous;
-        } else {
-            return null;
-        }
-    }
-
-    public Node addFirst(final E value, final String name) {
-        Args.notBlank(name, "Name");
-        Args.notNull(value, "Value");
-        final Node newNode = new Node(name, value);
-        final Node oldNode = master.next;
-        master.next = newNode;
-        newNode.previous = master;
-        newNode.next = oldNode;
-        oldNode.previous = newNode;
-        size++;
-        return newNode;
-    }
-
-    public Node addLast(final E value, final String name) {
-        Args.notBlank(name, "Name");
-        Args.notNull(value, "Value");
-        final Node newNode = new Node(name, value);
-        final Node oldNode = master.previous;
-        master.previous = newNode;
-        newNode.previous = oldNode;
-        newNode.next = master;
-        oldNode.next = newNode;
-        size++;
-        return newNode;
-    }
-
-    public Node find(final String name) {
-        Args.notBlank(name, "Name");
-        return doFind(name);
-    }
-
-    private Node doFind(final String name) {
-        Node current = master.next;
-        while (current != master) {
-            if (name.equals(current.name)) {
-                return current;
-            }
-            current = current.next;
-        }
-        return null;
-    }
-
-    public Node addBefore(final String existing, final E value, final String name) {
-        Args.notBlank(name, "Name");
-        Args.notNull(value, "Value");
-        final Node current = doFind(existing);
-        if (current == null) {
-            return null;
-        }
-        final Node newNode = new Node(name, value);
-        final Node previousNode = current.previous;
-        previousNode.next = newNode;
-        newNode.previous = previousNode;
-        newNode.next = current;
-        current.previous = newNode;
-        size++;
-        return newNode;
-    }
-
-    public Node addAfter(final String existing, final E value, final String name) {
-        Args.notBlank(name, "Name");
-        Args.notNull(value, "Value");
-        final Node current = doFind(existing);
-        if (current == null) {
-            return null;
-        }
-        final Node newNode = new Node(name, value);
-        final Node nextNode = current.next;
-        current.next = newNode;
-        newNode.previous = current;
-        newNode.next = nextNode;
-        nextNode.previous = newNode;
-        size++;
-        return newNode;
-    }
-
-    public boolean remove(final String name) {
-        final Node node = doFind(name);
-        if (node == null) {
-            return false;
-        }
-        node.previous.next = node.next;
-        node.next.previous = node.previous;
-        node.previous = null;
-        node.next = null;
-        size--;
-        return true;
-    }
-
-    public boolean replace(final String existing, final E value) {
-        final Node node = doFind(existing);
-        if (node == null) {
-            return false;
-        }
-        node.value = value;
-        return true;
-    }
-
-    public int getSize() {
-        return size;
-    }
-
-    public class Node {
-
-        private final String name;
-        private E value;
-        private Node previous;
-        private Node next;
-
-        Node(final String name, final E value) {
-            this.name = name;
-            this.value = value;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public E getValue() {
-            return value;
-        }
-
-        public Node getPrevious() {
-            if (previous != master) {
-                return previous;
-            } else {
-                return null;
-            }
-        }
-
-        public Node getNext() {
-            if (next != master) {
-                return next;
-            } else {
-                return null;
-            }
-        }
-
-        @Override
-        public String toString() {
-            return name + ": " + value;
-        }
-
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
index bcfb00c..11ccf4a 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
@@ -33,7 +33,6 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.ExceptionListener;
 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.ConnectionInitiator;
@@ -52,7 +51,6 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
 
     private final AsyncPushConsumerRegistry pushConsumerRegistry;
     private final DefaultConnectingIOReactor ioReactor;
-    private final ExceptionListener exceptionListener;
     private final ExecutorService executorService;
     private final AtomicReference<Status> status;
 
@@ -63,14 +61,6 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
         super();
         this.ioReactor = ioReactor;
         this.pushConsumerRegistry = pushConsumerRegistry;
-        this.exceptionListener = new ExceptionListener() {
-
-            @Override
-            public void onError(final Exception ex) {
-                log.error(ex.getMessage(), ex);
-            }
-
-        };
         this.executorService = Executors.newSingleThreadExecutor(threadFactory);
         this.status = new AtomicReference<>(Status.READY);
     }
@@ -82,11 +72,7 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
 
                 @Override
                 public void run() {
-                    try {
-                        ioReactor.execute();
-                    } catch (final Exception ex) {
-                        exceptionListener.onError(ex);
-                    }
+                    ioReactor.start();
                 }
             });
         }
@@ -116,8 +102,8 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
     }
 
     @Override
-    public final List<ExceptionEvent> getAuditLog() {
-        return ioReactor.getAuditLog();
+    public final List<ExceptionEvent> getExceptionLog() {
+        return ioReactor.getExceptionLog();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/BasicAsyncEntityProducer.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/BasicAsyncEntityProducer.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/BasicAsyncEntityProducer.java
deleted file mode 100644
index 7c804b4..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/BasicAsyncEntityProducer.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.async;
-
-import java.io.IOException;
-import java.util.Set;
-
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.nio.AsyncDataProducer;
-import org.apache.hc.core5.http.nio.AsyncEntityProducer;
-import org.apache.hc.core5.http.nio.DataStreamChannel;
-import org.apache.hc.core5.util.Args;
-
-public class BasicAsyncEntityProducer implements AsyncEntityProducer {
-
-    private final AsyncDataProducer dataProducer;
-    private final EntityDetails entityDetails;
-
-    BasicAsyncEntityProducer(final AsyncDataProducer dataProducer, final EntityDetails entityDetails) {
-        this.dataProducer = Args.notNull(dataProducer, "Data producer");
-        this.entityDetails = Args.notNull(entityDetails, "Entity details");
-    }
-
-    @Override
-    public void releaseResources() {
-        dataProducer.releaseResources();
-    }
-
-    @Override
-    public void failed(final Exception cause) {
-        dataProducer.releaseResources();
-    }
-
-    @Override
-    public long getContentLength() {
-        return entityDetails.getContentLength();
-    }
-
-    @Override
-    public String getContentType() {
-        return entityDetails.getContentType();
-    }
-
-    @Override
-    public String getContentEncoding() {
-        return entityDetails.getContentEncoding();
-    }
-
-    @Override
-    public boolean isChunked() {
-        return entityDetails.isChunked();
-    }
-
-    @Override
-    public Set<String> getTrailerNames() {
-        return entityDetails.getTrailerNames();
-    }
-
-    @Override
-    public int available() {
-        return dataProducer.available();
-    }
-
-    @Override
-    public void produce(final DataStreamChannel channel) throws IOException {
-        dataProducer.produce(channel);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/CloseableHttpAsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/CloseableHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/CloseableHttpAsyncClient.java
index 392ac6b..5526800 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/CloseableHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/CloseableHttpAsyncClient.java
@@ -62,7 +62,7 @@ public abstract class CloseableHttpAsyncClient implements HttpAsyncClient, Close
 
     public abstract IOReactorStatus getStatus();
 
-    public abstract List<ExceptionEvent> getAuditLog();
+    public abstract List<ExceptionEvent> getExceptionLog();
 
     public abstract void awaitShutdown(TimeValue waitTime) throws InterruptedException;
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
index 6884849..61b6abb 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
@@ -53,7 +53,6 @@ import org.apache.hc.client5.http.impl.DefaultConnectionKeepAliveStrategy;
 import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
 import org.apache.hc.client5.http.impl.DefaultUserTokenHandler;
 import org.apache.hc.client5.http.impl.IdleConnectionEvictor;
-import org.apache.hc.client5.http.impl.NamedElementChain;
 import org.apache.hc.client5.http.impl.NoopUserTokenHandler;
 import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
 import org.apache.hc.client5.http.impl.auth.CredSspSchemeFactory;
@@ -97,6 +96,7 @@ import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.config.Lookup;
+import org.apache.hc.core5.http.config.NamedElementChain;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
@@ -118,7 +118,6 @@ import org.apache.hc.core5.pool.ConnPoolControl;
 import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOReactorException;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
@@ -904,7 +903,7 @@ public class HttpAsyncClientBuilder {
                 new HandlerFactory<AsyncPushConsumer>() {
 
                     @Override
-                    public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
+                    public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
                         return pushConsumerRegistry.get(request);
                     }
 
@@ -914,23 +913,20 @@ public class HttpAsyncClientBuilder {
                 h1Config != null ? h1Config : H1Config.DEFAULT,
                 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
                 reuseStrategyCopy);
-        final DefaultConnectingIOReactor ioReactor;
-        try {
-            ioReactor = new DefaultConnectingIOReactor(
-                    ioEventHandlerFactory,
-                    ioReactorConfig != null ? ioReactorConfig : IOReactorConfig.DEFAULT,
-                    threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-dispatch", true),
-                    new Callback<IOSession>() {
+        final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
+                ioEventHandlerFactory,
+                ioReactorConfig != null ? ioReactorConfig : IOReactorConfig.DEFAULT,
+                threadFactory != null ? threadFactory : new DefaultThreadFactory("httpclient-dispatch", true),
+                null,
+                null,
+                new Callback<IOSession>() {
 
-                        @Override
-                        public void execute(final IOSession ioSession) {
-                            ioSession.addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
-                        }
+                    @Override
+                    public void execute(final IOSession ioSession) {
+                        ioSession.addFirst(new ShutdownCommand(ShutdownType.GRACEFUL));
+                    }
 
-                    });
-        } catch (final IOReactorException ex) {
-            throw new IllegalStateException(ex.getMessage(), ex);
-        }
+                });
 
         if (execInterceptors != null) {
             for (final ExecInterceptorEntry entry: execInterceptors) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
index 24a1c37..1419b44 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
@@ -36,7 +36,6 @@ import org.apache.hc.client5.http.impl.logging.LogAppendable;
 import org.apache.hc.client5.http.impl.logging.LoggingIOSession;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
@@ -44,7 +43,6 @@ import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.H1Config;
-import org.apache.hc.core5.http.impl.ConnectionListener;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.hc.core5.http.impl.Http1StreamListener;
 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
@@ -124,31 +122,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
                 || framePayloadLog.isDebugEnabled()
                 || flowCtrlLog.isDebugEnabled()) {
             final String id = ConnPoolSupport.getId(ioSession);
-            final ConnectionListener connectionListener = new ConnectionListener() {
-
-                @Override
-                public void onConnect(final HttpConnection connection) {
-                    if (streamLog.isDebugEnabled()) {
-                        streamLog.debug(id + ": " + connection + " connected");
-                    }
-                }
-
-                @Override
-                public void onDisconnect(final HttpConnection connection) {
-                    if (streamLog.isDebugEnabled()) {
-                        streamLog.debug(id + ": " + connection + " disconnected");
-                    }
-                }
-
-                @Override
-                public void onError(final HttpConnection connection, final Exception ex) {
-                    if (ex instanceof ConnectionClosedException) {
-                        return;
-                    }
-                    streamLog.error(id + ": " + ex.getMessage(), ex);
-                }
-
-            };
             final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
                     httpProcessor,
                     h1Config,
@@ -156,7 +129,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
                     http1ConnectionReuseStrategy,
                     http1ResponseParserFactory,
                     http1RequestWriterFactory,
-                    connectionListener,
                     new Http1StreamListener() {
 
                         @Override
@@ -196,7 +168,6 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
                     exchangeHandlerFactory,
                     h2Config,
                     charCodingConfig,
-                    connectionListener,
                     new Http2StreamListener() {
 
                         final FramePrinter framePrinter = new FramePrinter();
@@ -285,8 +256,7 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
                             loggingIOSession,
                             http1StreamHandlerFactory,
                             http2StreamHandlerFactory,
-                            attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy,
-                            connectionListener);
+                            attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
         } else {
             final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
                     httpProcessor,
@@ -295,19 +265,18 @@ public class HttpAsyncClientEventHandlerFactory implements IOEventHandlerFactory
                     http1ConnectionReuseStrategy,
                     http1ResponseParserFactory,
                     http1RequestWriterFactory,
-                    null, null);
+                    null);
             final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientHttp2StreamMultiplexerFactory(
                     httpProcessor,
                     exchangeHandlerFactory,
                     h2Config,
                     charCodingConfig,
-                    null, null);
+                    null);
             return new ClientHttpProtocolNegotiator(
                     ioSession,
                     http1StreamHandlerFactory,
                     http2StreamHandlerFactory,
-                    attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy,
-                    null);
+                    attachment instanceof HttpVersionPolicy ? (HttpVersionPolicy) attachment : versionPolicy);
         }
    }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
index c023632..e610029 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
@@ -43,7 +43,6 @@ import org.apache.hc.core5.http2.protocol.H2RequestContent;
 import org.apache.hc.core5.http2.protocol.H2RequestTargetHost;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOReactorException;
 import org.apache.hc.core5.util.VersionInfo;
 
 /**
@@ -95,18 +94,14 @@ public class HttpAsyncClients {
             final HttpVersionPolicy versionPolicy,
             final IOReactorConfig ioReactorConfig,
             final AsyncClientConnectionManager connmgr) {
-        try {
-            return new MinimalHttpAsyncClient(
-                    eventHandlerFactory,
-                    pushConsumerRegistry,
-                    versionPolicy,
-                    ioReactorConfig,
-                    new DefaultThreadFactory("httpclient-main", true),
-                    new DefaultThreadFactory("httpclient-dispatch", true),
-                    connmgr);
-        } catch (final IOReactorException ex) {
-            throw new IllegalStateException(ex.getMessage(), ex);
-        }
+        return new MinimalHttpAsyncClient(
+                eventHandlerFactory,
+                pushConsumerRegistry,
+                versionPolicy,
+                ioReactorConfig,
+                new DefaultThreadFactory("httpclient-main", true),
+                new DefaultThreadFactory("httpclient-dispatch", true),
+                connmgr);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAsyncEntityProducer.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAsyncEntityProducer.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAsyncEntityProducer.java
new file mode 100644
index 0000000..14840e5
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAsyncEntityProducer.java
@@ -0,0 +1,93 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.async;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.nio.AsyncDataProducer;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+
+final class InternalAsyncEntityProducer implements AsyncEntityProducer {
+
+    private final AsyncDataProducer dataProducer;
+    private final EntityDetails entityDetails;
+
+    InternalAsyncEntityProducer(final AsyncDataProducer dataProducer, final EntityDetails entityDetails) {
+        this.dataProducer = dataProducer;
+        this.entityDetails = entityDetails;
+    }
+
+    @Override
+    public void releaseResources() {
+        dataProducer.releaseResources();
+    }
+
+    @Override
+    public void failed(final Exception cause) {
+        dataProducer.releaseResources();
+    }
+
+    @Override
+    public long getContentLength() {
+        return entityDetails.getContentLength();
+    }
+
+    @Override
+    public String getContentType() {
+        return entityDetails.getContentType();
+    }
+
+    @Override
+    public String getContentEncoding() {
+        return entityDetails.getContentEncoding();
+    }
+
+    @Override
+    public boolean isChunked() {
+        return entityDetails.isChunked();
+    }
+
+    @Override
+    public Set<String> getTrailerNames() {
+        return entityDetails.getTrailerNames();
+    }
+
+    @Override
+    public int available() {
+        return dataProducer.available();
+    }
+
+    @Override
+    public void produce(final DataStreamChannel channel) throws IOException {
+        dataProducer.produce(channel);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
index 013e687..d001458 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
@@ -53,6 +53,8 @@ import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolVersion;
 import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncDataConsumer;
@@ -150,9 +152,9 @@ class InternalHttpAsyncClient extends AbstractHttpAsyncClientBase {
             log.debug(exchangeId + ": preparing request execution");
         }
 
-        //TODO remove when fixed in HttpCore
-        if (route.isTunnelled()) {
-            throw new HttpException("HTTP tunneling not supported");
+        final ProtocolVersion protocolVersion = clientContext.getProtocolVersion();
+        if (route.isTunnelled() && protocolVersion.greaterEquals(HttpVersion.HTTP_2_0)) {
+            throw new HttpException("HTTP/2 tunneling not supported");
         }
 
         setupContext(clientContext);
@@ -160,7 +162,7 @@ class InternalHttpAsyncClient extends AbstractHttpAsyncClientBase {
         final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, clientContext, execRuntime);
         execChain.execute(
                 ExecSupport.copy(request),
-                entityDetails != null ? new BasicAsyncEntityProducer(exchangeHandler, entityDetails) : null,
+                entityDetails != null ? new InternalAsyncEntityProducer(exchangeHandler, entityDetails) : null,
                 scope,
                 new AsyncExecCallback() {
 


Fwd: [6/6] httpcomponents-client git commit: Logging improvements

Posted by Gary Gregory <ga...@gmail.com>.
I see a TODO I left in there for when we release Log4j 2.9.0, and we just
did. I can do that over the weekend unless someone else gets to it first.

Gary
---------- Forwarded message ----------
From: <ol...@apache.org>
Date: Sep 1, 2017 12:15
Subject: [6/6] httpcomponents-client git commit: Logging improvements
To: <co...@hc.apache.org>
Cc:

Logging improvements
>
>
> Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
> Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/commit/e8f72b7c
> Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/tree/e8f72b7c
> Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/diff/e8f72b7c
>
> Branch: refs/heads/master
> Commit: e8f72b7c57e353b7fb1cc164f6f5c8e8bc8cbf28
> Parents: 1eb2218
> Author: Oleg Kalnichevski <ol...@apache.org>
> Authored: Fri Sep 1 20:11:04 2017 +0200
> Committer: Oleg Kalnichevski <ol...@apache.org>
> Committed: Fri Sep 1 20:11:04 2017 +0200
>
> ----------------------------------------------------------------------
>  .../hc/client5/http/impl/ConnPoolSupport.java   |   2 +
>  .../org/apache/hc/client5/http/impl/Wire.java   | 177 ++++++++++++
>  .../HttpAsyncClientEventHandlerFactory.java     |   2 -
>  .../impl/async/InternalHttpAsyncClient.java     |   2 +-
>  .../client5/http/impl/async/LogAppendable.java  |  78 ++++++
>  .../http/impl/async/LoggingIOSession.java       | 270 +++++++++++++++++++
>  .../io/DefaultManagedHttpClientConnection.java  |   1 -
>  .../http/impl/io/LoggingInputStream.java        | 139 ++++++++++
>  .../http/impl/io/LoggingOutputStream.java       | 104 +++++++
>  .../http/impl/io/LoggingSocketHolder.java       |  57 ++++
>  .../io/PoolingHttpClientConnectionManager.java  |  13 +-
>  ...olingHttpClientConnectionManagerBuilder.java |  12 -
>  .../http/impl/logging/LogAppendable.java        |  78 ------
>  .../http/impl/logging/LoggingIOSession.java     | 269 ------------------
>  .../http/impl/logging/LoggingInputStream.java   | 137 ----------
>  .../http/impl/logging/LoggingOutputStream.java  | 102 -------
>  .../http/impl/logging/LoggingSocketHolder.java  |  56 ----
>  .../hc/client5/http/impl/logging/Wire.java      | 175 ------------
>  .../PoolingAsyncClientConnectionManager.java    |   8 +-
>  ...lingAsyncClientConnectionManagerBuilder.java |  14 +-
>  20 files changed, 837 insertions(+), 859 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/ConnPoolSupport.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/ConnPoolSupport.java
> index e6650a4..3de413c 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/ConnPoolSupport.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/ConnPoolSupport.java
> @@ -27,10 +27,12 @@
>  package org.apache.hc.client5.http.impl;
>
>  import org.apache.hc.client5.http.HttpRoute;
> +import org.apache.hc.core5.annotation.Internal;
>  import org.apache.hc.core5.pool.ConnPoolControl;
>  import org.apache.hc.core5.pool.PoolStats;
>  import org.apache.hc.core5.util.Identifiable;
>
> +@Internal
>  public final class ConnPoolSupport {
>
>      public static String getId(final Object object) {
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/Wire.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
> new file mode 100644
> index 0000000..fd48ebd
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
> @@ -0,0 +1,177 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl;
> +
> +import java.nio.ByteBuffer;
> +
> +import org.apache.hc.core5.annotation.Internal;
> +import org.apache.hc.core5.util.Args;
> +import org.apache.logging.log4j.Logger;
> +
> +@Internal
> +public class Wire {
> +
> +    private static final int MAX_STRING_BUILDER_SIZE = 2048;
> +
> +    private static final ThreadLocal<StringBuilder> threadLocal = new
> ThreadLocal<>();
> +
> +    /**
> +     * Returns a {@code StringBuilder} that this Layout implementation
> can use to write the formatted log event to.
> +     *
> +     * @return a {@code StringBuilder}
> +     */
> +    private static StringBuilder getStringBuilder() {
> +        StringBuilder result = threadLocal.get();
> +        if (result == null) {
> +            result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
> +            threadLocal.set(result);
> +        }
> +        // TODO Delegate to Log4j's 2.9 StringBuilds.trimToMaxSize() when
> it is released.
> +        trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
> +        result.setLength(0);
> +        return result;
> +    }
> +
> +    /**
> +     * Ensures that the char[] array of the specified StringBuilder does
> not exceed the specified number of characters.
> +     * This method is useful to ensure that excessively long char[]
> arrays are not kept in memory forever.
> +     *
> +     * @param stringBuilder the StringBuilder to check
> +     * @param maxSize the maximum number of characters the StringBuilder
> is allowed to have
> +     */
> +    // TODO Delete wheb Log4j's 2.9 (see #trimToMaxSize(StringBuild))
> +    private static void trimToMaxSize(final StringBuilder stringBuilder,
> final int maxSize) {
> +        if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
> +            stringBuilder.setLength(maxSize);
> +            stringBuilder.trimToSize();
> +        }
> +    }
> +
> +    private final Logger log;
> +    private final String id;
> +
> +    public Wire(final Logger log, final String id) {
> +        super();
> +        this.log = log;
> +        this.id = id;
> +    }
> +
> +    private void wire(final String header, final byte[] b, final int pos,
> final int off) {
> +        final StringBuilder buffer = getStringBuilder();
> +        for (int i = 0; i < off; i++) {
> +            final int ch = b[pos + i];
> +            if (ch == 13) {
> +                buffer.append("[\\r]");
> +            } else if (ch == 10) {
> +                    buffer.append("[\\n]\"");
> +                    buffer.insert(0, "\"");
> +                    buffer.insert(0, header);
> +                    this.log.debug(this.id + " " + buffer.toString());
> +                    buffer.setLength(0);
> +            } else if ((ch < 32) || (ch > 127)) {
> +                buffer.append("[0x");
> +                buffer.append(Integer.toHexString(ch));
> +                buffer.append("]");
> +            } else {
> +                buffer.append((char) ch);
> +            }
> +        }
> +        if (buffer.length() > 0) {
> +            buffer.append('\"');
> +            buffer.insert(0, '\"');
> +            buffer.insert(0, header);
> +            this.log.debug(this.id + " " + buffer.toString());
> +        }
> +    }
> +
> +
> +    public boolean isEnabled() {
> +        return this.log.isDebugEnabled();
> +    }
> +
> +    public void output(final byte[] b, final int pos, final int off) {
> +        Args.notNull(b, "Output");
> +        wire(">> ", b, pos, off);
> +    }
> +
> +    public void input(final byte[] b, final int pos, final int off) {
> +        Args.notNull(b, "Input");
> +        wire("<< ", b, pos, off);
> +    }
> +
> +    public void output(final byte[] b) {
> +        Args.notNull(b, "Output");
> +        output(b, 0, b.length);
> +    }
> +
> +    public void input(final byte[] b) {
> +        Args.notNull(b, "Input");
> +        input(b, 0, b.length);
> +    }
> +
> +    public void output(final int b) {
> +        output(new byte[] {(byte) b});
> +    }
> +
> +    public void input(final int b) {
> +        input(new byte[] {(byte) b});
> +    }
> +
> +    public void output(final String s) {
> +        Args.notNull(s, "Output");
> +        output(s.getBytes());
> +    }
> +
> +    public void input(final String s) {
> +        Args.notNull(s, "Input");
> +        input(s.getBytes());
> +    }
> +
> +    public void output(final ByteBuffer b) {
> +        Args.notNull(b, "Output");
> +        if (b.hasArray()) {
> +            output(b.array(), b.arrayOffset() + b.position(),
> b.remaining());
> +        } else {
> +            final byte[] tmp = new byte[b.remaining()];
> +            b.get(tmp);
> +            output(tmp);
> +        }
> +    }
> +
> +    public void input(final ByteBuffer b) {
> +        Args.notNull(b, "Input");
> +        if (b.hasArray()) {
> +            input(b.array(), b.arrayOffset() + b.position(),
> b.remaining());
> +        } else {
> +            final byte[] tmp = new byte[b.remaining()];
> +            b.get(tmp);
> +            input(tmp);
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/HttpAsyncClientEventHandlerFactory.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/
> HttpAsyncClientEventHandlerFactory.java
> index 1419b44..95d9267 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/
> HttpAsyncClientEventHandlerFactory.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/
> HttpAsyncClientEventHandlerFactory.java
> @@ -32,8 +32,6 @@ import java.util.Iterator;
>  import java.util.List;
>
>  import org.apache.hc.client5.http.impl.ConnPoolSupport;
> -import org.apache.hc.client5.http.impl.logging.LogAppendable;
> -import org.apache.hc.client5.http.impl.logging.LoggingIOSession;
>  import org.apache.hc.core5.annotation.Contract;
>  import org.apache.hc.core5.annotation.ThreadingBehavior;
>  import org.apache.hc.core5.http.ConnectionReuseStrategy;
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/InternalHttpAsyncClient.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
> index d001458..c6f0d93 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/
> InternalHttpAsyncClient.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/
> InternalHttpAsyncClient.java
> @@ -248,7 +248,7 @@ class InternalHttpAsyncClient extends
> AbstractHttpAsyncClientBase {
>
>                      final HttpHost target = routePlanner.determineTargetHost(request,
> clientContext);
>                      final HttpRoute route = routePlanner.determineRoute(target,
> clientContext);
> -                    final String exchangeId = "ex-" +
> Long.toHexString(ExecSupport.getNextExecNumber());
> +                    final String exchangeId = String.format("ex-%08X",
> ExecSupport.getNextExecNumber());
>                      final AsyncExecRuntime execRuntime = new
> AsyncExecRuntimeImpl(log, connmgr, getConnectionInitiator(), versionPolicy);
>                      executeChain(exchangeId, execChain, route, request,
> entityDetails, exchangeHandler, clientContext, execRuntime);
>                  }
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/async/LogAppendable.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LogAppendable.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/LogAppendable.java
> new file mode 100644
> index 0000000..5d5070d
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/LogAppendable.java
> @@ -0,0 +1,78 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl.async;
> +
> +import java.io.IOException;
> +
> +import org.apache.logging.log4j.Logger;
> +
> +public final class LogAppendable implements Appendable {
> +
> +    private final Logger log;
> +    private final String prefix;
> +    private final StringBuilder buffer;
> +
> +    public LogAppendable(final Logger log, final String prefix) {
> +        this.log = log;
> +        this.prefix = prefix;
> +        this.buffer = new StringBuilder();
> +    }
> +
> +
> +    @Override
> +    public Appendable append(final CharSequence text) throws IOException {
> +        return append(text, 0, text.length());
> +    }
> +
> +    @Override
> +    public Appendable append(final CharSequence text, final int start,
> final int end) throws IOException {
> +        for (int i = start; i < end; i++) {
> +            append(text.charAt(i));
> +        }
> +        return this;
> +    }
> +
> +    @Override
> +    public Appendable append(final char ch) throws IOException {
> +        if (ch == '\n') {
> +            log.debug(prefix + " " + buffer.toString());
> +            buffer.setLength(0);
> +        } else if (ch != '\r') {
> +            buffer.append(ch);
> +        }
> +        return this;
> +    }
> +
> +    public void flush() {
> +        if (buffer.length() > 0) {
> +            log.debug(prefix + " " + buffer.toString());
> +            buffer.setLength(0);
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/async/LoggingIOSession.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/LoggingIOSession.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/async/LoggingIOSession.java
> new file mode 100644
> index 0000000..fad7f1e
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/async/LoggingIOSession.java
> @@ -0,0 +1,270 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl.async;
> +
> +import java.io.IOException;
> +import java.net.SocketAddress;
> +import java.nio.ByteBuffer;
> +import java.nio.channels.ByteChannel;
> +import java.nio.channels.SelectionKey;
> +
> +import javax.net.ssl.SSLContext;
> +
> +import org.apache.hc.client5.http.impl.Wire;
> +import org.apache.hc.core5.io.ShutdownType;
> +import org.apache.hc.core5.reactor.Command;
> +import org.apache.hc.core5.reactor.IOEventHandler;
> +import org.apache.hc.core5.reactor.TlsCapableIOSession;
> +import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
> +import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
> +import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
> +import org.apache.hc.core5.reactor.ssl.TlsDetails;
> +import org.apache.logging.log4j.Logger;
> +
> +class LoggingIOSession implements TlsCapableIOSession {
> +
> +    private final Logger log;
> +    private final Wire wirelog;
> +    private final String id;
> +    private final TlsCapableIOSession session;
> +    private final ByteChannel channel;
> +
> +    public LoggingIOSession(final TlsCapableIOSession session, final
> String id, final Logger log, final Logger wirelog) {
> +        super();
> +        this.session = session;
> +        this.id = id;
> +        this.log = log;
> +        this.wirelog = new Wire(wirelog, this.id);
> +        this.channel = new LoggingByteChannel();
> +    }
> +
> +    public LoggingIOSession(final TlsCapableIOSession session, final
> String id, final Logger log) {
> +        this(session, id, log, null);
> +    }
> +
> +    @Override
> +    public String getId() {
> +        return session.getId();
> +    }
> +
> +    @Override
> +    public void addLast(final Command command) {
> +        this.session.addLast(command);
> +    }
> +
> +    @Override
> +    public void addFirst(final Command command) {
> +        this.session.addFirst(command);
> +    }
> +
> +    @Override
> +    public Command getCommand() {
> +        return this.session.getCommand();
> +    }
> +
> +    @Override
> +    public ByteChannel channel() {
> +        return this.channel;
> +    }
> +
> +    @Override
> +    public SocketAddress getLocalAddress() {
> +        return this.session.getLocalAddress();
> +    }
> +
> +    @Override
> +    public SocketAddress getRemoteAddress() {
> +        return this.session.getRemoteAddress();
> +    }
> +
> +    @Override
> +    public int getEventMask() {
> +        return this.session.getEventMask();
> +    }
> +
> +    private static String formatOps(final int ops) {
> +        final StringBuilder buffer = new StringBuilder(6);
> +        buffer.append('[');
> +        if ((ops & SelectionKey.OP_READ) > 0) {
> +            buffer.append('r');
> +        }
> +        if ((ops & SelectionKey.OP_WRITE) > 0) {
> +            buffer.append('w');
> +        }
> +        if ((ops & SelectionKey.OP_ACCEPT) > 0) {
> +            buffer.append('a');
> +        }
> +        if ((ops & SelectionKey.OP_CONNECT) > 0) {
> +            buffer.append('c');
> +        }
> +        buffer.append(']');
> +        return buffer.toString();
> +    }
> +
> +    @Override
> +    public void setEventMask(final int ops) {
> +        this.session.setEventMask(ops);
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Event mask
> set " + formatOps(ops));
> +        }
> +    }
> +
> +    @Override
> +    public void setEvent(final int op) {
> +        this.session.setEvent(op);
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Event set "
> + formatOps(op));
> +        }
> +    }
> +
> +    @Override
> +    public void clearEvent(final int op) {
> +        this.session.clearEvent(op);
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Event
> cleared " + formatOps(op));
> +        }
> +    }
> +
> +    @Override
> +    public void close() {
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Close");
> +        }
> +        this.session.close();
> +    }
> +
> +    @Override
> +    public int getStatus() {
> +        return this.session.getStatus();
> +    }
> +
> +    @Override
> +    public boolean isClosed() {
> +        return this.session.isClosed();
> +    }
> +
> +    @Override
> +    public void shutdown(final ShutdownType shutdownType) {
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Shutdown "
> + shutdownType);
> +        }
> +        this.session.shutdown(shutdownType);
> +    }
> +
> +    @Override
> +    public int getSocketTimeout() {
> +        return this.session.getSocketTimeout();
> +    }
> +
> +    @Override
> +    public void setSocketTimeout(final int timeout) {
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.id + " " + this.session + ": Set timeout
> " + timeout);
> +        }
> +        this.session.setSocketTimeout(timeout);
> +    }
> +
> +    @Override
> +    public IOEventHandler getHandler() {
> +        return this.session.getHandler();
> +    }
> +
> +    @Override
> +    public void setHandler(final IOEventHandler handler) {
> +        this.session.setHandler(handler);
> +    }
> +
> +    @Override
> +    public void startTls(
> +            final SSLContext sslContext,
> +            final SSLBufferManagement sslBufferManagement,
> +            final SSLSessionInitializer initializer,
> +            final SSLSessionVerifier verifier) throws
> UnsupportedOperationException {
> +        session.startTls(sslContext, sslBufferManagement, initializer,
> verifier);
> +    }
> +
> +    @Override
> +    public TlsDetails getTlsDetails() {
> +        return session.getTlsDetails();
> +    }
> +
> +    @Override
> +    public String toString() {
> +        return this.id + " " + this.session.toString();
> +    }
> +
> +    class LoggingByteChannel implements ByteChannel {
> +
> +        @Override
> +        public int read(final ByteBuffer dst) throws IOException {
> +            final int bytesRead = session.channel().read(dst);
> +            if (log.isDebugEnabled()) {
> +                log.debug(id + " " + session + ": " + bytesRead + " bytes
> read");
> +            }
> +            if (bytesRead > 0 && wirelog.isEnabled()) {
> +                final ByteBuffer b = dst.duplicate();
> +                final int p = b.position();
> +                b.limit(p);
> +                b.position(p - bytesRead);
> +                wirelog.input(b);
> +            }
> +            return bytesRead;
> +        }
> +
> +        @Override
> +        public int write(final ByteBuffer src) throws IOException {
> +            final int byteWritten = session.channel().write(src);
> +            if (log.isDebugEnabled()) {
> +                log.debug(id + " " + session + ": " + byteWritten + "
> bytes written");
> +            }
> +            if (byteWritten > 0 && wirelog.isEnabled()) {
> +                final ByteBuffer b = src.duplicate();
> +                final int p = b.position();
> +                b.limit(p);
> +                b.position(p - byteWritten);
> +                wirelog.output(b);
> +            }
> +            return byteWritten;
> +        }
> +
> +        @Override
> +        public void close() throws IOException {
> +            if (log.isDebugEnabled()) {
> +                log.debug(id + " " + session + ": Channel close");
> +            }
> +            session.channel().close();
> +        }
> +
> +        @Override
> +        public boolean isOpen() {
> +            return session.channel().isOpen();
> +        }
> +
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> DefaultManagedHttpClientConnection.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
> index ac412ff..52dea86 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> DefaultManagedHttpClientConnection.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> DefaultManagedHttpClientConnection.java
> @@ -37,7 +37,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
>  import javax.net.ssl.SSLSession;
>  import javax.net.ssl.SSLSocket;
>
> -import org.apache.hc.client5.http.impl.logging.LoggingSocketHolder;
>  import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
>  import org.apache.hc.core5.http.ClassicHttpRequest;
>  import org.apache.hc.core5.http.ClassicHttpResponse;
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/LoggingInputStream.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingInputStream.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/io/LoggingInputStream.java
> new file mode 100644
> index 0000000..69aded2
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingInputStream.java
> @@ -0,0 +1,139 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl.io;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +
> +import org.apache.hc.client5.http.impl.Wire;
> +
> +class LoggingInputStream extends InputStream {
> +
> +    private final InputStream in;
> +    private final Wire wire;
> +
> +    public LoggingInputStream(final InputStream in, final Wire wire) {
> +        super();
> +        this.in = in;
> +        this.wire = wire;
> +    }
> +
> +    @Override
> +    public int read() throws IOException {
> +        try {
> +            final int b = in.read();
> +            if (b == -1) {
> +                wire.input("end of stream");
> +            } else {
> +                wire.input(b);
> +            }
> +            return b;
> +        } catch (final IOException ex) {
> +            wire.input("[read] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public int read(final byte[] b) throws IOException {
> +        try {
> +            final int bytesRead = in.read(b);
> +            if (bytesRead == -1) {
> +                wire.input("end of stream");
> +            } else if (bytesRead > 0) {
> +                wire.input(b, 0, bytesRead);
> +            }
> +            return bytesRead;
> +        } catch (final IOException ex) {
> +            wire.input("[read] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public int read(final byte[] b, final int off, final int len) throws
> IOException {
> +        try {
> +            final int bytesRead = in.read(b, off, len);
> +            if (bytesRead == -1) {
> +                wire.input("end of stream");
> +            } else if (bytesRead > 0) {
> +                wire.input(b, off, bytesRead);
> +            }
> +            return bytesRead;
> +        } catch (final IOException ex) {
> +            wire.input("[read] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public long skip(final long n) throws IOException {
> +        try {
> +            return super.skip(n);
> +        } catch (final IOException ex) {
> +            wire.input("[skip] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public int available() throws IOException {
> +        try {
> +            return in.available();
> +        } catch (final IOException ex) {
> +            wire.input("[available] I/O error : " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public void mark(final int readlimit) {
> +        super.mark(readlimit);
> +    }
> +
> +    @Override
> +    public void reset() throws IOException {
> +        super.reset();
> +    }
> +
> +    @Override
> +    public boolean markSupported() {
> +        return false;
> +    }
> +
> +    @Override
> +    public void close() throws IOException {
> +        try {
> +            in.close();
> +        } catch (final IOException ex) {
> +            wire.input("[close] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/LoggingOutputStream.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingOutputStream.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/io/LoggingOutputStream.java
> new file mode 100644
> index 0000000..7484ee3
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingOutputStream.java
> @@ -0,0 +1,104 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl.io;
> +
> +import java.io.IOException;
> +import java.io.OutputStream;
> +
> +import org.apache.hc.client5.http.impl.Wire;
> +
> +/**
> + * Internal class.
> + *
> + * @since 4.3
> + */
> +class LoggingOutputStream extends OutputStream {
> +
> +    private final OutputStream out;
> +    private final Wire wire;
> +
> +    public LoggingOutputStream(final OutputStream out, final Wire wire) {
> +        super();
> +        this.out = out;
> +        this.wire = wire;
> +    }
> +
> +    @Override
> +    public void write(final int b) throws IOException {
> +        try {
> +            out.write(b);
> +            wire.output(b);
> +        } catch (final IOException ex) {
> +            wire.output("[write] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public void write(final byte[] b) throws IOException {
> +        try {
> +            wire.output(b);
> +            out.write(b);
> +        } catch (final IOException ex) {
> +            wire.output("[write] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public void write(final byte[] b, final int off, final int len)
> throws IOException {
> +        try {
> +            wire.output(b, off, len);
> +            out.write(b, off, len);
> +        } catch (final IOException ex) {
> +            wire.output("[write] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public void flush() throws IOException {
> +        try {
> +            out.flush();
> +        } catch (final IOException ex) {
> +            wire.output("[flush] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +    @Override
> +    public void close() throws IOException {
> +        try {
> +            out.close();
> +        } catch (final IOException ex) {
> +            wire.output("[close] I/O error: " + ex.getMessage());
> +            throw ex;
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/LoggingSocketHolder.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingSocketHolder.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/io/LoggingSocketHolder.java
> new file mode 100644
> index 0000000..b7aae76
> --- /dev/null
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/io/LoggingSocketHolder.java
> @@ -0,0 +1,57 @@
> +/*
> + * ====================================================================
> + * 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.hc.client5.http.impl.io;
> +
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.io.OutputStream;
> +import java.net.Socket;
> +
> +import org.apache.hc.client5.http.impl.Wire;
> +import org.apache.hc.core5.http.impl.io.SocketHolder;
> +import org.apache.logging.log4j.Logger;
> +
> +class LoggingSocketHolder extends SocketHolder {
> +
> +    private final Wire wire;
> +
> +    public LoggingSocketHolder(final Socket socket, final String id,
> final Logger log) {
> +        super(socket);
> +        this.wire = new Wire(log, id);
> +    }
> +
> +    @Override
> +    protected InputStream getInputStream(final Socket socket) throws
> IOException {
> +        return new LoggingInputStream(super.getInputStream(socket),
> wire);
> +    }
> +
> +    @Override
> +    protected OutputStream getOutputStream(final Socket socket) throws
> IOException {
> +        return new LoggingOutputStream(super.getOutputStream(socket),
> wire);
> +    }
> +}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
> index 4dca6a7..ecb237e 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManager.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManager.java
> @@ -64,7 +64,6 @@ import org.apache.hc.core5.http.io.
> HttpConnectionFactory;
>  import org.apache.hc.core5.http.protocol.HttpContext;
>  import org.apache.hc.core5.io.ShutdownType;
>  import org.apache.hc.core5.pool.ConnPoolControl;
> -import org.apache.hc.core5.pool.ConnPoolListener;
>  import org.apache.hc.core5.pool.PoolEntry;
>  import org.apache.hc.core5.pool.PoolReusePolicy;
>  import org.apache.hc.core5.pool.PoolStats;
> @@ -128,7 +127,7 @@ public class PoolingHttpClientConnectionManager
>      }
>
>      public PoolingHttpClientConnectionManager(final TimeValue
> timeToLive) {
> -        this(getDefaultRegistry(), null, null ,null,
> PoolReusePolicy.LIFO, null, timeToLive);
> +        this(getDefaultRegistry(), null, null ,null,
> PoolReusePolicy.LIFO, timeToLive);
>      }
>
>      public PoolingHttpClientConnectionManager(
> @@ -157,7 +156,7 @@ public class PoolingHttpClientConnectionManager
>              final Registry<ConnectionSocketFactory>
> socketFactoryRegistry,
>              final HttpConnectionFactory<ManagedHttpClientConnection>
> connFactory,
>              final DnsResolver dnsResolver) {
> -        this(socketFactoryRegistry, connFactory, null, dnsResolver,
> PoolReusePolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
> +        this(socketFactoryRegistry, connFactory, null, dnsResolver,
> PoolReusePolicy.LIFO, TimeValue.NEG_ONE_MILLISECONDS);
>      }
>
>      public PoolingHttpClientConnectionManager(
> @@ -166,23 +165,21 @@ public class PoolingHttpClientConnectionManager
>              final SchemePortResolver schemePortResolver,
>              final DnsResolver dnsResolver,
>              final PoolReusePolicy poolReusePolicy,
> -            final ConnPoolListener<HttpRoute> connPoolListener,
>              final TimeValue timeToLive) {
>          this(new DefaultHttpClientConnectionOperator(socketFactoryRegistry,
> schemePortResolver, dnsResolver),
> -            connFactory, poolReusePolicy, connPoolListener, timeToLive);
> +            connFactory, poolReusePolicy, timeToLive);
>      }
>
>      public PoolingHttpClientConnectionManager(
>              final HttpClientConnectionOperator
> httpClientConnectionOperator,
>              final HttpConnectionFactory<ManagedHttpClientConnection>
> connFactory,
>              final PoolReusePolicy poolReusePolicy,
> -            final ConnPoolListener<HttpRoute> connPoolListener,
>              final TimeValue timeToLive) {
>          super();
>          this.connectionOperator = Args.notNull(httpClientConnectionOperator,
> "Connection operator");
>          this.connFactory = connFactory != null ? connFactory :
> ManagedHttpClientConnectionFactory.INSTANCE;
> -        this.pool = new StrictConnPool<>(
> -                DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
> DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, poolReusePolicy,
> connPoolListener);
> +        this.pool = new StrictConnPool<>(DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
> DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive,
> +                poolReusePolicy, null);
>          this.closed = new AtomicBoolean(false);
>      }
>
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/io/PoolingHttpClientConnectionMan
> agerBuilder.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManagerBuilder.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManagerBuilder.java
> index 76c36b3..0e3b553 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManagerBuilder.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/
> PoolingHttpClientConnectionManagerBuilder.java
> @@ -28,7 +28,6 @@
>  package org.apache.hc.client5.http.impl.io;
>
>  import org.apache.hc.client5.http.DnsResolver;
> -import org.apache.hc.client5.http.HttpRoute;
>  import org.apache.hc.client5.http.SchemePortResolver;
>  import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
>  import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
> @@ -38,7 +37,6 @@ import org.apache.hc.client5.http.ssl.
> SSLConnectionSocketFactory;
>  import org.apache.hc.core5.http.config.RegistryBuilder;
>  import org.apache.hc.core5.http.config.SocketConfig;
>  import org.apache.hc.core5.http.io.HttpConnectionFactory;
> -import org.apache.hc.core5.pool.ConnPoolListener;
>  import org.apache.hc.core5.pool.PoolReusePolicy;
>  import org.apache.hc.core5.util.TimeValue;
>
> @@ -75,7 +73,6 @@ public class PoolingHttpClientConnectionManagerBuilder {
>      private SchemePortResolver schemePortResolver;
>      private DnsResolver dnsResolver;
>      private PoolReusePolicy poolReusePolicy;
> -    private ConnPoolListener<HttpRoute> connPoolListener;
>      private SocketConfig defaultSocketConfig;
>
>      private boolean systemProperties;
> @@ -137,14 +134,6 @@ public class PoolingHttpClientConnectionManagerBuilder
> {
>      }
>
>      /**
> -     * Assigns {@link ConnPoolListener} instance.
> -     */
> -    public final PoolingHttpClientConnectionManagerBuilder
> setConnPoolListener(final ConnPoolListener<HttpRoute> connPoolListener) {
> -        this.connPoolListener = connPoolListener;
> -        return this;
> -    }
> -
> -    /**
>       * Assigns maximum total connection value.
>       */
>      public final PoolingHttpClientConnectionManagerBuilder
> setMaxConnTotal(final int maxConnTotal) {
> @@ -210,7 +199,6 @@ public class PoolingHttpClientConnectionManagerBuilder
> {
>                  schemePortResolver,
>                  dnsResolver,
>                  poolReusePolicy,
> -                connPoolListener,
>                  timeToLive != null ? timeToLive : TimeValue.NEG_ONE_
> MILLISECONDS);
>          poolingmgr.setValidateAfterInactivity(
> this.validateAfterInactivity);
>          if (defaultSocketConfig != null) {
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/LogAppendable.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LogAppendable.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/logging/LogAppendable.java
> deleted file mode 100644
> index 181bb95..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LogAppendable.java
> +++ /dev/null
> @@ -1,78 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.io.IOException;
> -
> -import org.apache.logging.log4j.Logger;
> -
> -public final class LogAppendable implements Appendable {
> -
> -    private final Logger log;
> -    private final String prefix;
> -    private final StringBuilder buffer;
> -
> -    public LogAppendable(final Logger log, final String prefix) {
> -        this.log = log;
> -        this.prefix = prefix;
> -        this.buffer = new StringBuilder();
> -    }
> -
> -
> -    @Override
> -    public Appendable append(final CharSequence text) throws IOException {
> -        return append(text, 0, text.length());
> -    }
> -
> -    @Override
> -    public Appendable append(final CharSequence text, final int start,
> final int end) throws IOException {
> -        for (int i = start; i < end; i++) {
> -            append(text.charAt(i));
> -        }
> -        return this;
> -    }
> -
> -    @Override
> -    public Appendable append(final char ch) throws IOException {
> -        if (ch == '\n') {
> -            log.debug(prefix + " " + buffer.toString());
> -            buffer.setLength(0);
> -        } else if (ch != '\r') {
> -            buffer.append(ch);
> -        }
> -        return this;
> -    }
> -
> -    public void flush() {
> -        if (buffer.length() > 0) {
> -            log.debug(prefix + " " + buffer.toString());
> -            buffer.setLength(0);
> -        }
> -    }
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/LoggingIOSession.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LoggingIOSession.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/logging/LoggingIOSession.java
> deleted file mode 100644
> index c750f7a..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LoggingIOSession.java
> +++ /dev/null
> @@ -1,269 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.io.IOException;
> -import java.net.SocketAddress;
> -import java.nio.ByteBuffer;
> -import java.nio.channels.ByteChannel;
> -import java.nio.channels.SelectionKey;
> -
> -import javax.net.ssl.SSLContext;
> -
> -import org.apache.hc.core5.io.ShutdownType;
> -import org.apache.hc.core5.reactor.Command;
> -import org.apache.hc.core5.reactor.IOEventHandler;
> -import org.apache.hc.core5.reactor.TlsCapableIOSession;
> -import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
> -import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
> -import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
> -import org.apache.hc.core5.reactor.ssl.TlsDetails;
> -import org.apache.logging.log4j.Logger;
> -
> -public class LoggingIOSession implements TlsCapableIOSession {
> -
> -    private final Logger log;
> -    private final Wire wirelog;
> -    private final String id;
> -    private final TlsCapableIOSession session;
> -    private final ByteChannel channel;
> -
> -    public LoggingIOSession(final TlsCapableIOSession session, final
> String id, final Logger log, final Logger wirelog) {
> -        super();
> -        this.session = session;
> -        this.id = id;
> -        this.log = log;
> -        this.wirelog = new Wire(wirelog, this.id);
> -        this.channel = new LoggingByteChannel();
> -    }
> -
> -    public LoggingIOSession(final TlsCapableIOSession session, final
> String id, final Logger log) {
> -        this(session, id, log, null);
> -    }
> -
> -    @Override
> -    public String getId() {
> -        return session.getId();
> -    }
> -
> -    @Override
> -    public void addLast(final Command command) {
> -        this.session.addLast(command);
> -    }
> -
> -    @Override
> -    public void addFirst(final Command command) {
> -        this.session.addFirst(command);
> -    }
> -
> -    @Override
> -    public Command getCommand() {
> -        return this.session.getCommand();
> -    }
> -
> -    @Override
> -    public ByteChannel channel() {
> -        return this.channel;
> -    }
> -
> -    @Override
> -    public SocketAddress getLocalAddress() {
> -        return this.session.getLocalAddress();
> -    }
> -
> -    @Override
> -    public SocketAddress getRemoteAddress() {
> -        return this.session.getRemoteAddress();
> -    }
> -
> -    @Override
> -    public int getEventMask() {
> -        return this.session.getEventMask();
> -    }
> -
> -    private static String formatOps(final int ops) {
> -        final StringBuilder buffer = new StringBuilder(6);
> -        buffer.append('[');
> -        if ((ops & SelectionKey.OP_READ) > 0) {
> -            buffer.append('r');
> -        }
> -        if ((ops & SelectionKey.OP_WRITE) > 0) {
> -            buffer.append('w');
> -        }
> -        if ((ops & SelectionKey.OP_ACCEPT) > 0) {
> -            buffer.append('a');
> -        }
> -        if ((ops & SelectionKey.OP_CONNECT) > 0) {
> -            buffer.append('c');
> -        }
> -        buffer.append(']');
> -        return buffer.toString();
> -    }
> -
> -    @Override
> -    public void setEventMask(final int ops) {
> -        this.session.setEventMask(ops);
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Event mask
> set " + formatOps(ops));
> -        }
> -    }
> -
> -    @Override
> -    public void setEvent(final int op) {
> -        this.session.setEvent(op);
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Event set "
> + formatOps(op));
> -        }
> -    }
> -
> -    @Override
> -    public void clearEvent(final int op) {
> -        this.session.clearEvent(op);
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Event
> cleared " + formatOps(op));
> -        }
> -    }
> -
> -    @Override
> -    public void close() {
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Close");
> -        }
> -        this.session.close();
> -    }
> -
> -    @Override
> -    public int getStatus() {
> -        return this.session.getStatus();
> -    }
> -
> -    @Override
> -    public boolean isClosed() {
> -        return this.session.isClosed();
> -    }
> -
> -    @Override
> -    public void shutdown(final ShutdownType shutdownType) {
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Shutdown "
> + shutdownType);
> -        }
> -        this.session.shutdown(shutdownType);
> -    }
> -
> -    @Override
> -    public int getSocketTimeout() {
> -        return this.session.getSocketTimeout();
> -    }
> -
> -    @Override
> -    public void setSocketTimeout(final int timeout) {
> -        if (this.log.isDebugEnabled()) {
> -            this.log.debug(this.id + " " + this.session + ": Set timeout
> " + timeout);
> -        }
> -        this.session.setSocketTimeout(timeout);
> -    }
> -
> -    @Override
> -    public IOEventHandler getHandler() {
> -        return this.session.getHandler();
> -    }
> -
> -    @Override
> -    public void setHandler(final IOEventHandler handler) {
> -        this.session.setHandler(handler);
> -    }
> -
> -    @Override
> -    public void startTls(
> -            final SSLContext sslContext,
> -            final SSLBufferManagement sslBufferManagement,
> -            final SSLSessionInitializer initializer,
> -            final SSLSessionVerifier verifier) throws
> UnsupportedOperationException {
> -        session.startTls(sslContext, sslBufferManagement, initializer,
> verifier);
> -    }
> -
> -    @Override
> -    public TlsDetails getTlsDetails() {
> -        return session.getTlsDetails();
> -    }
> -
> -    @Override
> -    public String toString() {
> -        return this.id + " " + this.session.toString();
> -    }
> -
> -    class LoggingByteChannel implements ByteChannel {
> -
> -        @Override
> -        public int read(final ByteBuffer dst) throws IOException {
> -            final int bytesRead = session.channel().read(dst);
> -            if (log.isDebugEnabled()) {
> -                log.debug(id + " " + session + ": " + bytesRead + " bytes
> read");
> -            }
> -            if (bytesRead > 0 && wirelog.isEnabled()) {
> -                final ByteBuffer b = dst.duplicate();
> -                final int p = b.position();
> -                b.limit(p);
> -                b.position(p - bytesRead);
> -                wirelog.input(b);
> -            }
> -            return bytesRead;
> -        }
> -
> -        @Override
> -        public int write(final ByteBuffer src) throws IOException {
> -            final int byteWritten = session.channel().write(src);
> -            if (log.isDebugEnabled()) {
> -                log.debug(id + " " + session + ": " + byteWritten + "
> bytes written");
> -            }
> -            if (byteWritten > 0 && wirelog.isEnabled()) {
> -                final ByteBuffer b = src.duplicate();
> -                final int p = b.position();
> -                b.limit(p);
> -                b.position(p - byteWritten);
> -                wirelog.output(b);
> -            }
> -            return byteWritten;
> -        }
> -
> -        @Override
> -        public void close() throws IOException {
> -            if (log.isDebugEnabled()) {
> -                log.debug(id + " " + session + ": Channel close");
> -            }
> -            session.channel().close();
> -        }
> -
> -        @Override
> -        public boolean isOpen() {
> -            return session.channel().isOpen();
> -        }
> -
> -    }
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/LoggingInputStream.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LoggingInputStream.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/logging/LoggingInputStream.java
> deleted file mode 100644
> index 018fae6..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/
> LoggingInputStream.java
> +++ /dev/null
> @@ -1,137 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.io.IOException;
> -import java.io.InputStream;
> -
> -class LoggingInputStream extends InputStream {
> -
> -    private final InputStream in;
> -    private final Wire wire;
> -
> -    public LoggingInputStream(final InputStream in, final Wire wire) {
> -        super();
> -        this.in = in;
> -        this.wire = wire;
> -    }
> -
> -    @Override
> -    public int read() throws IOException {
> -        try {
> -            final int b = in.read();
> -            if (b == -1) {
> -                wire.input("end of stream");
> -            } else {
> -                wire.input(b);
> -            }
> -            return b;
> -        } catch (final IOException ex) {
> -            wire.input("[read] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public int read(final byte[] b) throws IOException {
> -        try {
> -            final int bytesRead = in.read(b);
> -            if (bytesRead == -1) {
> -                wire.input("end of stream");
> -            } else if (bytesRead > 0) {
> -                wire.input(b, 0, bytesRead);
> -            }
> -            return bytesRead;
> -        } catch (final IOException ex) {
> -            wire.input("[read] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public int read(final byte[] b, final int off, final int len) throws
> IOException {
> -        try {
> -            final int bytesRead = in.read(b, off, len);
> -            if (bytesRead == -1) {
> -                wire.input("end of stream");
> -            } else if (bytesRead > 0) {
> -                wire.input(b, off, bytesRead);
> -            }
> -            return bytesRead;
> -        } catch (final IOException ex) {
> -            wire.input("[read] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public long skip(final long n) throws IOException {
> -        try {
> -            return super.skip(n);
> -        } catch (final IOException ex) {
> -            wire.input("[skip] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public int available() throws IOException {
> -        try {
> -            return in.available();
> -        } catch (final IOException ex) {
> -            wire.input("[available] I/O error : " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public void mark(final int readlimit) {
> -        super.mark(readlimit);
> -    }
> -
> -    @Override
> -    public void reset() throws IOException {
> -        super.reset();
> -    }
> -
> -    @Override
> -    public boolean markSupported() {
> -        return false;
> -    }
> -
> -    @Override
> -    public void close() throws IOException {
> -        try {
> -            in.close();
> -        } catch (final IOException ex) {
> -            wire.input("[close] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/LoggingOutputStream.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LoggingOutputStream.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/logging/LoggingOutputStream.java
> deleted file mode 100644
> index ec82d1f..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/
> LoggingOutputStream.java
> +++ /dev/null
> @@ -1,102 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.io.IOException;
> -import java.io.OutputStream;
> -
> -/**
> - * Internal class.
> - *
> - * @since 4.3
> - */
> -class LoggingOutputStream extends OutputStream {
> -
> -    private final OutputStream out;
> -    private final Wire wire;
> -
> -    public LoggingOutputStream(final OutputStream out, final Wire wire) {
> -        super();
> -        this.out = out;
> -        this.wire = wire;
> -    }
> -
> -    @Override
> -    public void write(final int b) throws IOException {
> -        try {
> -            out.write(b);
> -            wire.output(b);
> -        } catch (final IOException ex) {
> -            wire.output("[write] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public void write(final byte[] b) throws IOException {
> -        try {
> -            wire.output(b);
> -            out.write(b);
> -        } catch (final IOException ex) {
> -            wire.output("[write] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public void write(final byte[] b, final int off, final int len)
> throws IOException {
> -        try {
> -            wire.output(b, off, len);
> -            out.write(b, off, len);
> -        } catch (final IOException ex) {
> -            wire.output("[write] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public void flush() throws IOException {
> -        try {
> -            out.flush();
> -        } catch (final IOException ex) {
> -            wire.output("[flush] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -    @Override
> -    public void close() throws IOException {
> -        try {
> -            out.close();
> -        } catch (final IOException ex) {
> -            wire.output("[close] I/O error: " + ex.getMessage());
> -            throw ex;
> -        }
> -    }
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/LoggingSocketHolder.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/LoggingSocketHolder.java b/httpclient5/src/main/java/
> org/apache/hc/client5/http/impl/logging/LoggingSocketHolder.java
> deleted file mode 100644
> index ddde402..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/
> LoggingSocketHolder.java
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.io.IOException;
> -import java.io.InputStream;
> -import java.io.OutputStream;
> -import java.net.Socket;
> -
> -import org.apache.hc.core5.http.impl.io.SocketHolder;
> -import org.apache.logging.log4j.Logger;
> -
> -public class LoggingSocketHolder extends SocketHolder {
> -
> -    private final Wire wire;
> -
> -    public LoggingSocketHolder(final Socket socket, final String id,
> final Logger log) {
> -        super(socket);
> -        this.wire = new Wire(log, id);
> -    }
> -
> -    @Override
> -    protected InputStream getInputStream(final Socket socket) throws
> IOException {
> -        return new LoggingInputStream(super.getInputStream(socket),
> wire);
> -    }
> -
> -    @Override
> -    protected OutputStream getOutputStream(final Socket socket) throws
> IOException {
> -        return new LoggingOutputStream(super.getOutputStream(socket),
> wire);
> -    }
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/logging/Wire.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/Wire.java
> deleted file mode 100644
> index 8bd9e4f..0000000
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/logging/Wire.java
> +++ /dev/null
> @@ -1,175 +0,0 @@
> -/*
> - * ====================================================================
> - * 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.hc.client5.http.impl.logging;
> -
> -import java.nio.ByteBuffer;
> -
> -import org.apache.hc.core5.util.Args;
> -import org.apache.logging.log4j.Logger;
> -
> -class Wire {
> -
> -    private static final int MAX_STRING_BUILDER_SIZE = 2048;
> -
> -    private static final ThreadLocal<StringBuilder> threadLocal = new
> ThreadLocal<>();
> -
> -    /**
> -     * Returns a {@code StringBuilder} that this Layout implementation
> can use to write the formatted log event to.
> -     *
> -     * @return a {@code StringBuilder}
> -     */
> -    private static StringBuilder getStringBuilder() {
> -        StringBuilder result = threadLocal.get();
> -        if (result == null) {
> -            result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
> -            threadLocal.set(result);
> -        }
> -        // TODO Delegate to Log4j's 2.9 StringBuilds.trimToMaxSize() when
> it is released.
> -        trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
> -        result.setLength(0);
> -        return result;
> -    }
> -
> -    /**
> -     * Ensures that the char[] array of the specified StringBuilder does
> not exceed the specified number of characters.
> -     * This method is useful to ensure that excessively long char[]
> arrays are not kept in memory forever.
> -     *
> -     * @param stringBuilder the StringBuilder to check
> -     * @param maxSize the maximum number of characters the StringBuilder
> is allowed to have
> -     */
> -    // TODO Delete wheb Log4j's 2.9 (see #trimToMaxSize(StringBuild))
> -    private static void trimToMaxSize(final StringBuilder stringBuilder,
> final int maxSize) {
> -        if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
> -            stringBuilder.setLength(maxSize);
> -            stringBuilder.trimToSize();
> -        }
> -    }
> -
> -    private final Logger log;
> -    private final String id;
> -
> -    Wire(final Logger log, final String id) {
> -        super();
> -        this.log = log;
> -        this.id = id;
> -    }
> -
> -    private void wire(final String header, final byte[] b, final int pos,
> final int off) {
> -        final StringBuilder buffer = getStringBuilder();
> -        for (int i = 0; i < off; i++) {
> -            final int ch = b[pos + i];
> -            if (ch == 13) {
> -                buffer.append("[\\r]");
> -            } else if (ch == 10) {
> -                    buffer.append("[\\n]\"");
> -                    buffer.insert(0, "\"");
> -                    buffer.insert(0, header);
> -                    this.log.debug(this.id + " " + buffer.toString());
> -                    buffer.setLength(0);
> -            } else if ((ch < 32) || (ch > 127)) {
> -                buffer.append("[0x");
> -                buffer.append(Integer.toHexString(ch));
> -                buffer.append("]");
> -            } else {
> -                buffer.append((char) ch);
> -            }
> -        }
> -        if (buffer.length() > 0) {
> -            buffer.append('\"');
> -            buffer.insert(0, '\"');
> -            buffer.insert(0, header);
> -            this.log.debug(this.id + " " + buffer.toString());
> -        }
> -    }
> -
> -
> -    public boolean isEnabled() {
> -        return this.log.isDebugEnabled();
> -    }
> -
> -    public void output(final byte[] b, final int pos, final int off) {
> -        Args.notNull(b, "Output");
> -        wire(">> ", b, pos, off);
> -    }
> -
> -    public void input(final byte[] b, final int pos, final int off) {
> -        Args.notNull(b, "Input");
> -        wire("<< ", b, pos, off);
> -    }
> -
> -    public void output(final byte[] b) {
> -        Args.notNull(b, "Output");
> -        output(b, 0, b.length);
> -    }
> -
> -    public void input(final byte[] b) {
> -        Args.notNull(b, "Input");
> -        input(b, 0, b.length);
> -    }
> -
> -    public void output(final int b) {
> -        output(new byte[] {(byte) b});
> -    }
> -
> -    public void input(final int b) {
> -        input(new byte[] {(byte) b});
> -    }
> -
> -    public void output(final String s) {
> -        Args.notNull(s, "Output");
> -        output(s.getBytes());
> -    }
> -
> -    public void input(final String s) {
> -        Args.notNull(s, "Input");
> -        input(s.getBytes());
> -    }
> -
> -    public void output(final ByteBuffer b) {
> -        Args.notNull(b, "Output");
> -        if (b.hasArray()) {
> -            output(b.array(), b.arrayOffset() + b.position(),
> b.remaining());
> -        } else {
> -            final byte[] tmp = new byte[b.remaining()];
> -            b.get(tmp);
> -            output(tmp);
> -        }
> -    }
> -
> -    public void input(final ByteBuffer b) {
> -        Args.notNull(b, "Input");
> -        if (b.hasArray()) {
> -            input(b.array(), b.arrayOffset() + b.position(),
> b.remaining());
> -        } else {
> -            final byte[] tmp = new byte[b.remaining()];
> -            b.get(tmp);
> -            input(tmp);
> -        }
> -    }
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/nio/PoolingAsyncClientConnectionManager.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManager.java
> index 59d37bb..93ce8eb 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManager.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManager.java
> @@ -58,7 +58,6 @@ import org.apache.hc.core5.http2.nio.
> command.PingCommand;
>  import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
>  import org.apache.hc.core5.io.ShutdownType;
>  import org.apache.hc.core5.pool.ConnPoolControl;
> -import org.apache.hc.core5.pool.ConnPoolListener;
>  import org.apache.hc.core5.pool.PoolEntry;
>  import org.apache.hc.core5.pool.PoolReusePolicy;
>  import org.apache.hc.core5.pool.PoolStats;
> @@ -106,10 +105,9 @@ public class PoolingAsyncClientConnectionManager
> implements AsyncClientConnectio
>              final SchemePortResolver schemePortResolver,
>              final DnsResolver dnsResolver,
>              final TimeValue timeToLive,
> -            final PoolReusePolicy poolReusePolicy,
> -            final ConnPoolListener<HttpRoute> connPoolListener) {
> +            final PoolReusePolicy poolReusePolicy) {
>          this.connectionOperator = new AsyncClientConnectionOperator(schemePortResolver,
> dnsResolver, tlsStrategyLookup);
> -        this.pool = new StrictConnPool<>(20, 50, timeToLive,
> poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO,
> connPoolListener);
> +        this.pool = new StrictConnPool<>(20, 50, timeToLive,
> poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, null);
>          this.closed = new AtomicBoolean(false);
>      }
>
> @@ -400,7 +398,7 @@ public class PoolingAsyncClientConnectionManager
> implements AsyncClientConnectio
>
>          InternalConnectionEndpoint(final PoolEntry<HttpRoute,
> ManagedAsyncClientConnection> poolEntry) {
>              this.poolEntryRef = new AtomicReference<>(poolEntry);
> -            this.id = "ep-" + Long.toHexString(COUNT.incrementAndGet());
> +            this.id = String.format("ep-%08X", COUNT.getAndIncrement());
>          }
>
>          @Override
>
> http://git-wip-us.apache.org/repos/asf/httpcomponents-
> client/blob/e8f72b7c/httpclient5/src/main/java/org/
> apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionMa
> nagerBuilder.java
> ----------------------------------------------------------------------
> diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/
> impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
> b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManagerBuilder.java
> index 9a840ad..ed2e42d 100644
> --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManagerBuilder.java
> +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/
> PoolingAsyncClientConnectionManagerBuilder.java
> @@ -31,12 +31,10 @@ import java.security.AccessController;
>  import java.security.PrivilegedAction;
>
>  import org.apache.hc.client5.http.DnsResolver;
> -import org.apache.hc.client5.http.HttpRoute;
>  import org.apache.hc.client5.http.SchemePortResolver;
>  import org.apache.hc.client5.http.ssl.H2TlsStrategy;
>  import org.apache.hc.core5.http.config.RegistryBuilder;
>  import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
> -import org.apache.hc.core5.pool.ConnPoolListener;
>  import org.apache.hc.core5.pool.PoolReusePolicy;
>  import org.apache.hc.core5.util.TimeValue;
>
> @@ -72,7 +70,6 @@ public class PoolingAsyncClientConnectionManagerBuilder
> {
>      private SchemePortResolver schemePortResolver;
>      private DnsResolver dnsResolver;
>      private PoolReusePolicy poolReusePolicy;
> -    private ConnPoolListener<HttpRoute> connPoolListener;
>
>      private boolean systemProperties;
>
> @@ -124,14 +121,6 @@ public class PoolingAsyncClientConnectionManagerBuilder
> {
>      }
>
>      /**
> -     * Assigns {@link ConnPoolListener} instance.
> -     */
> -    public final PoolingAsyncClientConnectionManagerBuilder
> setConnPoolListener(final ConnPoolListener<HttpRoute> connPoolListener) {
> -        this.connPoolListener = connPoolListener;
> -        return this;
> -    }
> -
> -    /**
>       * Assigns maximum total connection value.
>       */
>      public final PoolingAsyncClientConnectionManagerBuilder
> setMaxConnTotal(final int maxConnTotal) {
> @@ -184,8 +173,7 @@ public class PoolingAsyncClientConnectionManagerBuilder
> {
>                  schemePortResolver,
>                  dnsResolver,
>                  timeToLive,
> -                poolReusePolicy,
> -                connPoolListener);
> +                poolReusePolicy);
>          poolingmgr.setValidateAfterInactivity(
> this.validateAfterInactivity);
>          if (maxConnTotal > 0) {
>              poolingmgr.setMaxTotal(maxConnTotal);
>
>

[6/6] httpcomponents-client git commit: Logging improvements

Posted by ol...@apache.org.
Logging improvements


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/e8f72b7c
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/e8f72b7c
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/e8f72b7c

Branch: refs/heads/master
Commit: e8f72b7c57e353b7fb1cc164f6f5c8e8bc8cbf28
Parents: 1eb2218
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Fri Sep 1 20:11:04 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Fri Sep 1 20:11:04 2017 +0200

----------------------------------------------------------------------
 .../hc/client5/http/impl/ConnPoolSupport.java   |   2 +
 .../org/apache/hc/client5/http/impl/Wire.java   | 177 ++++++++++++
 .../HttpAsyncClientEventHandlerFactory.java     |   2 -
 .../impl/async/InternalHttpAsyncClient.java     |   2 +-
 .../client5/http/impl/async/LogAppendable.java  |  78 ++++++
 .../http/impl/async/LoggingIOSession.java       | 270 +++++++++++++++++++
 .../io/DefaultManagedHttpClientConnection.java  |   1 -
 .../http/impl/io/LoggingInputStream.java        | 139 ++++++++++
 .../http/impl/io/LoggingOutputStream.java       | 104 +++++++
 .../http/impl/io/LoggingSocketHolder.java       |  57 ++++
 .../io/PoolingHttpClientConnectionManager.java  |  13 +-
 ...olingHttpClientConnectionManagerBuilder.java |  12 -
 .../http/impl/logging/LogAppendable.java        |  78 ------
 .../http/impl/logging/LoggingIOSession.java     | 269 ------------------
 .../http/impl/logging/LoggingInputStream.java   | 137 ----------
 .../http/impl/logging/LoggingOutputStream.java  | 102 -------
 .../http/impl/logging/LoggingSocketHolder.java  |  56 ----
 .../hc/client5/http/impl/logging/Wire.java      | 175 ------------
 .../PoolingAsyncClientConnectionManager.java    |   8 +-
 ...lingAsyncClientConnectionManagerBuilder.java |  14 +-
 20 files changed, 837 insertions(+), 859 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java
index e6650a4..3de413c 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/ConnPoolSupport.java
@@ -27,10 +27,12 @@
 package org.apache.hc.client5.http.impl;
 
 import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.pool.ConnPoolControl;
 import org.apache.hc.core5.pool.PoolStats;
 import org.apache.hc.core5.util.Identifiable;
 
+@Internal
 public final class ConnPoolSupport {
 
     public static String getId(final Object object) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
new file mode 100644
index 0000000..fd48ebd
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Wire.java
@@ -0,0 +1,177 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.util.Args;
+import org.apache.logging.log4j.Logger;
+
+@Internal
+public class Wire {
+
+    private static final int MAX_STRING_BUILDER_SIZE = 2048;
+
+    private static final ThreadLocal<StringBuilder> threadLocal = new ThreadLocal<>();
+
+    /**
+     * Returns a {@code StringBuilder} that this Layout implementation can use to write the formatted log event to.
+     *
+     * @return a {@code StringBuilder}
+     */
+    private static StringBuilder getStringBuilder() {
+        StringBuilder result = threadLocal.get();
+        if (result == null) {
+            result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
+            threadLocal.set(result);
+        }
+        // TODO Delegate to Log4j's 2.9 StringBuilds.trimToMaxSize() when it is released.
+        trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
+        result.setLength(0);
+        return result;
+    }
+
+    /**
+     * Ensures that the char[] array of the specified StringBuilder does not exceed the specified number of characters.
+     * This method is useful to ensure that excessively long char[] arrays are not kept in memory forever.
+     *
+     * @param stringBuilder the StringBuilder to check
+     * @param maxSize the maximum number of characters the StringBuilder is allowed to have
+     */
+    // TODO Delete wheb Log4j's 2.9 (see #trimToMaxSize(StringBuild))
+    private static void trimToMaxSize(final StringBuilder stringBuilder, final int maxSize) {
+        if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
+            stringBuilder.setLength(maxSize);
+            stringBuilder.trimToSize();
+        }
+    }
+
+    private final Logger log;
+    private final String id;
+
+    public Wire(final Logger log, final String id) {
+        super();
+        this.log = log;
+        this.id = id;
+    }
+
+    private void wire(final String header, final byte[] b, final int pos, final int off) {
+        final StringBuilder buffer = getStringBuilder();
+        for (int i = 0; i < off; i++) {
+            final int ch = b[pos + i];
+            if (ch == 13) {
+                buffer.append("[\\r]");
+            } else if (ch == 10) {
+                    buffer.append("[\\n]\"");
+                    buffer.insert(0, "\"");
+                    buffer.insert(0, header);
+                    this.log.debug(this.id + " " + buffer.toString());
+                    buffer.setLength(0);
+            } else if ((ch < 32) || (ch > 127)) {
+                buffer.append("[0x");
+                buffer.append(Integer.toHexString(ch));
+                buffer.append("]");
+            } else {
+                buffer.append((char) ch);
+            }
+        }
+        if (buffer.length() > 0) {
+            buffer.append('\"');
+            buffer.insert(0, '\"');
+            buffer.insert(0, header);
+            this.log.debug(this.id + " " + buffer.toString());
+        }
+    }
+
+
+    public boolean isEnabled() {
+        return this.log.isDebugEnabled();
+    }
+
+    public void output(final byte[] b, final int pos, final int off) {
+        Args.notNull(b, "Output");
+        wire(">> ", b, pos, off);
+    }
+
+    public void input(final byte[] b, final int pos, final int off) {
+        Args.notNull(b, "Input");
+        wire("<< ", b, pos, off);
+    }
+
+    public void output(final byte[] b) {
+        Args.notNull(b, "Output");
+        output(b, 0, b.length);
+    }
+
+    public void input(final byte[] b) {
+        Args.notNull(b, "Input");
+        input(b, 0, b.length);
+    }
+
+    public void output(final int b) {
+        output(new byte[] {(byte) b});
+    }
+
+    public void input(final int b) {
+        input(new byte[] {(byte) b});
+    }
+
+    public void output(final String s) {
+        Args.notNull(s, "Output");
+        output(s.getBytes());
+    }
+
+    public void input(final String s) {
+        Args.notNull(s, "Input");
+        input(s.getBytes());
+    }
+
+    public void output(final ByteBuffer b) {
+        Args.notNull(b, "Output");
+        if (b.hasArray()) {
+            output(b.array(), b.arrayOffset() + b.position(), b.remaining());
+        } else {
+            final byte[] tmp = new byte[b.remaining()];
+            b.get(tmp);
+            output(tmp);
+        }
+    }
+
+    public void input(final ByteBuffer b) {
+        Args.notNull(b, "Input");
+        if (b.hasArray()) {
+            input(b.array(), b.arrayOffset() + b.position(), b.remaining());
+        } else {
+            final byte[] tmp = new byte[b.remaining()];
+            b.get(tmp);
+            input(tmp);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
index 1419b44..95d9267 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientEventHandlerFactory.java
@@ -32,8 +32,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.hc.client5.http.impl.ConnPoolSupport;
-import org.apache.hc.client5.http.impl.logging.LogAppendable;
-import org.apache.hc.client5.http.impl.logging.LoggingIOSession;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
index d001458..c6f0d93 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncClient.java
@@ -248,7 +248,7 @@ class InternalHttpAsyncClient extends AbstractHttpAsyncClientBase {
 
                     final HttpHost target = routePlanner.determineTargetHost(request, clientContext);
                     final HttpRoute route = routePlanner.determineRoute(target, clientContext);
-                    final String exchangeId = "ex-" + Long.toHexString(ExecSupport.getNextExecNumber());
+                    final String exchangeId = String.format("ex-%08X", ExecSupport.getNextExecNumber());
                     final AsyncExecRuntime execRuntime = new AsyncExecRuntimeImpl(log, connmgr, getConnectionInitiator(), versionPolicy);
                     executeChain(exchangeId, execChain, route, request, entityDetails, exchangeHandler, clientContext, execRuntime);
                 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LogAppendable.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LogAppendable.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LogAppendable.java
new file mode 100644
index 0000000..5d5070d
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LogAppendable.java
@@ -0,0 +1,78 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.async;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.Logger;
+
+public final class LogAppendable implements Appendable {
+
+    private final Logger log;
+    private final String prefix;
+    private final StringBuilder buffer;
+
+    public LogAppendable(final Logger log, final String prefix) {
+        this.log = log;
+        this.prefix = prefix;
+        this.buffer = new StringBuilder();
+    }
+
+
+    @Override
+    public Appendable append(final CharSequence text) throws IOException {
+        return append(text, 0, text.length());
+    }
+
+    @Override
+    public Appendable append(final CharSequence text, final int start, final int end) throws IOException {
+        for (int i = start; i < end; i++) {
+            append(text.charAt(i));
+        }
+        return this;
+    }
+
+    @Override
+    public Appendable append(final char ch) throws IOException {
+        if (ch == '\n') {
+            log.debug(prefix + " " + buffer.toString());
+            buffer.setLength(0);
+        } else if (ch != '\r') {
+            buffer.append(ch);
+        }
+        return this;
+    }
+
+    public void flush() {
+        if (buffer.length() > 0) {
+            log.debug(prefix + " " + buffer.toString());
+            buffer.setLength(0);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingIOSession.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingIOSession.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingIOSession.java
new file mode 100644
index 0000000..fad7f1e
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingIOSession.java
@@ -0,0 +1,270 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.async;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SelectionKey;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.hc.client5.http.impl.Wire;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.reactor.Command;
+import org.apache.hc.core5.reactor.IOEventHandler;
+import org.apache.hc.core5.reactor.TlsCapableIOSession;
+import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
+import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
+import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
+import org.apache.hc.core5.reactor.ssl.TlsDetails;
+import org.apache.logging.log4j.Logger;
+
+class LoggingIOSession implements TlsCapableIOSession {
+
+    private final Logger log;
+    private final Wire wirelog;
+    private final String id;
+    private final TlsCapableIOSession session;
+    private final ByteChannel channel;
+
+    public LoggingIOSession(final TlsCapableIOSession session, final String id, final Logger log, final Logger wirelog) {
+        super();
+        this.session = session;
+        this.id = id;
+        this.log = log;
+        this.wirelog = new Wire(wirelog, this.id);
+        this.channel = new LoggingByteChannel();
+    }
+
+    public LoggingIOSession(final TlsCapableIOSession session, final String id, final Logger log) {
+        this(session, id, log, null);
+    }
+
+    @Override
+    public String getId() {
+        return session.getId();
+    }
+
+    @Override
+    public void addLast(final Command command) {
+        this.session.addLast(command);
+    }
+
+    @Override
+    public void addFirst(final Command command) {
+        this.session.addFirst(command);
+    }
+
+    @Override
+    public Command getCommand() {
+        return this.session.getCommand();
+    }
+
+    @Override
+    public ByteChannel channel() {
+        return this.channel;
+    }
+
+    @Override
+    public SocketAddress getLocalAddress() {
+        return this.session.getLocalAddress();
+    }
+
+    @Override
+    public SocketAddress getRemoteAddress() {
+        return this.session.getRemoteAddress();
+    }
+
+    @Override
+    public int getEventMask() {
+        return this.session.getEventMask();
+    }
+
+    private static String formatOps(final int ops) {
+        final StringBuilder buffer = new StringBuilder(6);
+        buffer.append('[');
+        if ((ops & SelectionKey.OP_READ) > 0) {
+            buffer.append('r');
+        }
+        if ((ops & SelectionKey.OP_WRITE) > 0) {
+            buffer.append('w');
+        }
+        if ((ops & SelectionKey.OP_ACCEPT) > 0) {
+            buffer.append('a');
+        }
+        if ((ops & SelectionKey.OP_CONNECT) > 0) {
+            buffer.append('c');
+        }
+        buffer.append(']');
+        return buffer.toString();
+    }
+
+    @Override
+    public void setEventMask(final int ops) {
+        this.session.setEventMask(ops);
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Event mask set " + formatOps(ops));
+        }
+    }
+
+    @Override
+    public void setEvent(final int op) {
+        this.session.setEvent(op);
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Event set " + formatOps(op));
+        }
+    }
+
+    @Override
+    public void clearEvent(final int op) {
+        this.session.clearEvent(op);
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Event cleared " + formatOps(op));
+        }
+    }
+
+    @Override
+    public void close() {
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Close");
+        }
+        this.session.close();
+    }
+
+    @Override
+    public int getStatus() {
+        return this.session.getStatus();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return this.session.isClosed();
+    }
+
+    @Override
+    public void shutdown(final ShutdownType shutdownType) {
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Shutdown " + shutdownType);
+        }
+        this.session.shutdown(shutdownType);
+    }
+
+    @Override
+    public int getSocketTimeout() {
+        return this.session.getSocketTimeout();
+    }
+
+    @Override
+    public void setSocketTimeout(final int timeout) {
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.id + " " + this.session + ": Set timeout " + timeout);
+        }
+        this.session.setSocketTimeout(timeout);
+    }
+
+    @Override
+    public IOEventHandler getHandler() {
+        return this.session.getHandler();
+    }
+
+    @Override
+    public void setHandler(final IOEventHandler handler) {
+        this.session.setHandler(handler);
+    }
+
+    @Override
+    public void startTls(
+            final SSLContext sslContext,
+            final SSLBufferManagement sslBufferManagement,
+            final SSLSessionInitializer initializer,
+            final SSLSessionVerifier verifier) throws UnsupportedOperationException {
+        session.startTls(sslContext, sslBufferManagement, initializer, verifier);
+    }
+
+    @Override
+    public TlsDetails getTlsDetails() {
+        return session.getTlsDetails();
+    }
+
+    @Override
+    public String toString() {
+        return this.id + " " + this.session.toString();
+    }
+
+    class LoggingByteChannel implements ByteChannel {
+
+        @Override
+        public int read(final ByteBuffer dst) throws IOException {
+            final int bytesRead = session.channel().read(dst);
+            if (log.isDebugEnabled()) {
+                log.debug(id + " " + session + ": " + bytesRead + " bytes read");
+            }
+            if (bytesRead > 0 && wirelog.isEnabled()) {
+                final ByteBuffer b = dst.duplicate();
+                final int p = b.position();
+                b.limit(p);
+                b.position(p - bytesRead);
+                wirelog.input(b);
+            }
+            return bytesRead;
+        }
+
+        @Override
+        public int write(final ByteBuffer src) throws IOException {
+            final int byteWritten = session.channel().write(src);
+            if (log.isDebugEnabled()) {
+                log.debug(id + " " + session + ": " + byteWritten + " bytes written");
+            }
+            if (byteWritten > 0 && wirelog.isEnabled()) {
+                final ByteBuffer b = src.duplicate();
+                final int p = b.position();
+                b.limit(p);
+                b.position(p - byteWritten);
+                wirelog.output(b);
+            }
+            return byteWritten;
+        }
+
+        @Override
+        public void close() throws IOException {
+            if (log.isDebugEnabled()) {
+                log.debug(id + " " + session + ": Channel close");
+            }
+            session.channel().close();
+        }
+
+        @Override
+        public boolean isOpen() {
+            return session.channel().isOpen();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
index ac412ff..52dea86 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/DefaultManagedHttpClientConnection.java
@@ -37,7 +37,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 
-import org.apache.hc.client5.http.impl.logging.LoggingSocketHolder;
 import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingInputStream.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingInputStream.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingInputStream.java
new file mode 100644
index 0000000..69aded2
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingInputStream.java
@@ -0,0 +1,139 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.hc.client5.http.impl.Wire;
+
+class LoggingInputStream extends InputStream {
+
+    private final InputStream in;
+    private final Wire wire;
+
+    public LoggingInputStream(final InputStream in, final Wire wire) {
+        super();
+        this.in = in;
+        this.wire = wire;
+    }
+
+    @Override
+    public int read() throws IOException {
+        try {
+            final int b = in.read();
+            if (b == -1) {
+                wire.input("end of stream");
+            } else {
+                wire.input(b);
+            }
+            return b;
+        } catch (final IOException ex) {
+            wire.input("[read] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public int read(final byte[] b) throws IOException {
+        try {
+            final int bytesRead = in.read(b);
+            if (bytesRead == -1) {
+                wire.input("end of stream");
+            } else if (bytesRead > 0) {
+                wire.input(b, 0, bytesRead);
+            }
+            return bytesRead;
+        } catch (final IOException ex) {
+            wire.input("[read] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        try {
+            final int bytesRead = in.read(b, off, len);
+            if (bytesRead == -1) {
+                wire.input("end of stream");
+            } else if (bytesRead > 0) {
+                wire.input(b, off, bytesRead);
+            }
+            return bytesRead;
+        } catch (final IOException ex) {
+            wire.input("[read] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public long skip(final long n) throws IOException {
+        try {
+            return super.skip(n);
+        } catch (final IOException ex) {
+            wire.input("[skip] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public int available() throws IOException {
+        try {
+            return in.available();
+        } catch (final IOException ex) {
+            wire.input("[available] I/O error : " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public void mark(final int readlimit) {
+        super.mark(readlimit);
+    }
+
+    @Override
+    public void reset() throws IOException {
+        super.reset();
+    }
+
+    @Override
+    public boolean markSupported() {
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            in.close();
+        } catch (final IOException ex) {
+            wire.input("[close] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingOutputStream.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingOutputStream.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingOutputStream.java
new file mode 100644
index 0000000..7484ee3
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingOutputStream.java
@@ -0,0 +1,104 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.hc.client5.http.impl.Wire;
+
+/**
+ * Internal class.
+ *
+ * @since 4.3
+ */
+class LoggingOutputStream extends OutputStream {
+
+    private final OutputStream out;
+    private final Wire wire;
+
+    public LoggingOutputStream(final OutputStream out, final Wire wire) {
+        super();
+        this.out = out;
+        this.wire = wire;
+    }
+
+    @Override
+    public void write(final int b) throws IOException {
+        try {
+            out.write(b);
+            wire.output(b);
+        } catch (final IOException ex) {
+            wire.output("[write] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public void write(final byte[] b) throws IOException {
+        try {
+            wire.output(b);
+            out.write(b);
+        } catch (final IOException ex) {
+            wire.output("[write] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public void write(final byte[] b, final int off, final int len) throws IOException {
+        try {
+            wire.output(b, off, len);
+            out.write(b, off, len);
+        } catch (final IOException ex) {
+            wire.output("[write] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        try {
+            out.flush();
+        } catch (final IOException ex) {
+            wire.output("[flush] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            out.close();
+        } catch (final IOException ex) {
+            wire.output("[close] I/O error: " + ex.getMessage());
+            throw ex;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingSocketHolder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingSocketHolder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingSocketHolder.java
new file mode 100644
index 0000000..b7aae76
--- /dev/null
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/LoggingSocketHolder.java
@@ -0,0 +1,57 @@
+/*
+ * ====================================================================
+ * 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.hc.client5.http.impl.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.apache.hc.client5.http.impl.Wire;
+import org.apache.hc.core5.http.impl.io.SocketHolder;
+import org.apache.logging.log4j.Logger;
+
+class LoggingSocketHolder extends SocketHolder {
+
+    private final Wire wire;
+
+    public LoggingSocketHolder(final Socket socket, final String id, final Logger log) {
+        super(socket);
+        this.wire = new Wire(log, id);
+    }
+
+    @Override
+    protected InputStream getInputStream(final Socket socket) throws IOException {
+        return new LoggingInputStream(super.getInputStream(socket), wire);
+    }
+
+    @Override
+    protected OutputStream getOutputStream(final Socket socket) throws IOException {
+        return new LoggingOutputStream(super.getOutputStream(socket), wire);
+    }
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
index 4dca6a7..ecb237e 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManager.java
@@ -64,7 +64,6 @@ import org.apache.hc.core5.http.io.HttpConnectionFactory;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.pool.ConnPoolControl;
-import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.PoolEntry;
 import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.pool.PoolStats;
@@ -128,7 +127,7 @@ public class PoolingHttpClientConnectionManager
     }
 
     public PoolingHttpClientConnectionManager(final TimeValue timeToLive) {
-        this(getDefaultRegistry(), null, null ,null, PoolReusePolicy.LIFO, null, timeToLive);
+        this(getDefaultRegistry(), null, null ,null, PoolReusePolicy.LIFO, timeToLive);
     }
 
     public PoolingHttpClientConnectionManager(
@@ -157,7 +156,7 @@ public class PoolingHttpClientConnectionManager
             final Registry<ConnectionSocketFactory> socketFactoryRegistry,
             final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
             final DnsResolver dnsResolver) {
-        this(socketFactoryRegistry, connFactory, null, dnsResolver, PoolReusePolicy.LIFO, null, TimeValue.NEG_ONE_MILLISECONDS);
+        this(socketFactoryRegistry, connFactory, null, dnsResolver, PoolReusePolicy.LIFO, TimeValue.NEG_ONE_MILLISECONDS);
     }
 
     public PoolingHttpClientConnectionManager(
@@ -166,23 +165,21 @@ public class PoolingHttpClientConnectionManager
             final SchemePortResolver schemePortResolver,
             final DnsResolver dnsResolver,
             final PoolReusePolicy poolReusePolicy,
-            final ConnPoolListener<HttpRoute> connPoolListener,
             final TimeValue timeToLive) {
         this(new DefaultHttpClientConnectionOperator(socketFactoryRegistry, schemePortResolver, dnsResolver),
-            connFactory, poolReusePolicy, connPoolListener, timeToLive);
+            connFactory, poolReusePolicy, timeToLive);
     }
 
     public PoolingHttpClientConnectionManager(
             final HttpClientConnectionOperator httpClientConnectionOperator,
             final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
             final PoolReusePolicy poolReusePolicy,
-            final ConnPoolListener<HttpRoute> connPoolListener,
             final TimeValue timeToLive) {
         super();
         this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
         this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
-        this.pool = new StrictConnPool<>(
-                DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive, poolReusePolicy, connPoolListener);
+        this.pool = new StrictConnPool<>(DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive,
+                poolReusePolicy, null);
         this.closed = new AtomicBoolean(false);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
index 76c36b3..0e3b553 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/io/PoolingHttpClientConnectionManagerBuilder.java
@@ -28,7 +28,6 @@
 package org.apache.hc.client5.http.impl.io;
 
 import org.apache.hc.client5.http.DnsResolver;
-import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.SchemePortResolver;
 import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
 import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
@@ -38,7 +37,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.config.SocketConfig;
 import org.apache.hc.core5.http.io.HttpConnectionFactory;
-import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.util.TimeValue;
 
@@ -75,7 +73,6 @@ public class PoolingHttpClientConnectionManagerBuilder {
     private SchemePortResolver schemePortResolver;
     private DnsResolver dnsResolver;
     private PoolReusePolicy poolReusePolicy;
-    private ConnPoolListener<HttpRoute> connPoolListener;
     private SocketConfig defaultSocketConfig;
 
     private boolean systemProperties;
@@ -137,14 +134,6 @@ public class PoolingHttpClientConnectionManagerBuilder {
     }
 
     /**
-     * Assigns {@link ConnPoolListener} instance.
-     */
-    public final PoolingHttpClientConnectionManagerBuilder setConnPoolListener(final ConnPoolListener<HttpRoute> connPoolListener) {
-        this.connPoolListener = connPoolListener;
-        return this;
-    }
-
-    /**
      * Assigns maximum total connection value.
      */
     public final PoolingHttpClientConnectionManagerBuilder setMaxConnTotal(final int maxConnTotal) {
@@ -210,7 +199,6 @@ public class PoolingHttpClientConnectionManagerBuilder {
                 schemePortResolver,
                 dnsResolver,
                 poolReusePolicy,
-                connPoolListener,
                 timeToLive != null ? timeToLive : TimeValue.NEG_ONE_MILLISECONDS);
         poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
         if (defaultSocketConfig != null) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LogAppendable.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LogAppendable.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LogAppendable.java
deleted file mode 100644
index 181bb95..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LogAppendable.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.io.IOException;
-
-import org.apache.logging.log4j.Logger;
-
-public final class LogAppendable implements Appendable {
-
-    private final Logger log;
-    private final String prefix;
-    private final StringBuilder buffer;
-
-    public LogAppendable(final Logger log, final String prefix) {
-        this.log = log;
-        this.prefix = prefix;
-        this.buffer = new StringBuilder();
-    }
-
-
-    @Override
-    public Appendable append(final CharSequence text) throws IOException {
-        return append(text, 0, text.length());
-    }
-
-    @Override
-    public Appendable append(final CharSequence text, final int start, final int end) throws IOException {
-        for (int i = start; i < end; i++) {
-            append(text.charAt(i));
-        }
-        return this;
-    }
-
-    @Override
-    public Appendable append(final char ch) throws IOException {
-        if (ch == '\n') {
-            log.debug(prefix + " " + buffer.toString());
-            buffer.setLength(0);
-        } else if (ch != '\r') {
-            buffer.append(ch);
-        }
-        return this;
-    }
-
-    public void flush() {
-        if (buffer.length() > 0) {
-            log.debug(prefix + " " + buffer.toString());
-            buffer.setLength(0);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingIOSession.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingIOSession.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingIOSession.java
deleted file mode 100644
index c750f7a..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingIOSession.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.ByteChannel;
-import java.nio.channels.SelectionKey;
-
-import javax.net.ssl.SSLContext;
-
-import org.apache.hc.core5.io.ShutdownType;
-import org.apache.hc.core5.reactor.Command;
-import org.apache.hc.core5.reactor.IOEventHandler;
-import org.apache.hc.core5.reactor.TlsCapableIOSession;
-import org.apache.hc.core5.reactor.ssl.SSLBufferManagement;
-import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
-import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
-import org.apache.hc.core5.reactor.ssl.TlsDetails;
-import org.apache.logging.log4j.Logger;
-
-public class LoggingIOSession implements TlsCapableIOSession {
-
-    private final Logger log;
-    private final Wire wirelog;
-    private final String id;
-    private final TlsCapableIOSession session;
-    private final ByteChannel channel;
-
-    public LoggingIOSession(final TlsCapableIOSession session, final String id, final Logger log, final Logger wirelog) {
-        super();
-        this.session = session;
-        this.id = id;
-        this.log = log;
-        this.wirelog = new Wire(wirelog, this.id);
-        this.channel = new LoggingByteChannel();
-    }
-
-    public LoggingIOSession(final TlsCapableIOSession session, final String id, final Logger log) {
-        this(session, id, log, null);
-    }
-
-    @Override
-    public String getId() {
-        return session.getId();
-    }
-
-    @Override
-    public void addLast(final Command command) {
-        this.session.addLast(command);
-    }
-
-    @Override
-    public void addFirst(final Command command) {
-        this.session.addFirst(command);
-    }
-
-    @Override
-    public Command getCommand() {
-        return this.session.getCommand();
-    }
-
-    @Override
-    public ByteChannel channel() {
-        return this.channel;
-    }
-
-    @Override
-    public SocketAddress getLocalAddress() {
-        return this.session.getLocalAddress();
-    }
-
-    @Override
-    public SocketAddress getRemoteAddress() {
-        return this.session.getRemoteAddress();
-    }
-
-    @Override
-    public int getEventMask() {
-        return this.session.getEventMask();
-    }
-
-    private static String formatOps(final int ops) {
-        final StringBuilder buffer = new StringBuilder(6);
-        buffer.append('[');
-        if ((ops & SelectionKey.OP_READ) > 0) {
-            buffer.append('r');
-        }
-        if ((ops & SelectionKey.OP_WRITE) > 0) {
-            buffer.append('w');
-        }
-        if ((ops & SelectionKey.OP_ACCEPT) > 0) {
-            buffer.append('a');
-        }
-        if ((ops & SelectionKey.OP_CONNECT) > 0) {
-            buffer.append('c');
-        }
-        buffer.append(']');
-        return buffer.toString();
-    }
-
-    @Override
-    public void setEventMask(final int ops) {
-        this.session.setEventMask(ops);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event mask set " + formatOps(ops));
-        }
-    }
-
-    @Override
-    public void setEvent(final int op) {
-        this.session.setEvent(op);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event set " + formatOps(op));
-        }
-    }
-
-    @Override
-    public void clearEvent(final int op) {
-        this.session.clearEvent(op);
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Event cleared " + formatOps(op));
-        }
-    }
-
-    @Override
-    public void close() {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Close");
-        }
-        this.session.close();
-    }
-
-    @Override
-    public int getStatus() {
-        return this.session.getStatus();
-    }
-
-    @Override
-    public boolean isClosed() {
-        return this.session.isClosed();
-    }
-
-    @Override
-    public void shutdown(final ShutdownType shutdownType) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Shutdown " + shutdownType);
-        }
-        this.session.shutdown(shutdownType);
-    }
-
-    @Override
-    public int getSocketTimeout() {
-        return this.session.getSocketTimeout();
-    }
-
-    @Override
-    public void setSocketTimeout(final int timeout) {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.id + " " + this.session + ": Set timeout " + timeout);
-        }
-        this.session.setSocketTimeout(timeout);
-    }
-
-    @Override
-    public IOEventHandler getHandler() {
-        return this.session.getHandler();
-    }
-
-    @Override
-    public void setHandler(final IOEventHandler handler) {
-        this.session.setHandler(handler);
-    }
-
-    @Override
-    public void startTls(
-            final SSLContext sslContext,
-            final SSLBufferManagement sslBufferManagement,
-            final SSLSessionInitializer initializer,
-            final SSLSessionVerifier verifier) throws UnsupportedOperationException {
-        session.startTls(sslContext, sslBufferManagement, initializer, verifier);
-    }
-
-    @Override
-    public TlsDetails getTlsDetails() {
-        return session.getTlsDetails();
-    }
-
-    @Override
-    public String toString() {
-        return this.id + " " + this.session.toString();
-    }
-
-    class LoggingByteChannel implements ByteChannel {
-
-        @Override
-        public int read(final ByteBuffer dst) throws IOException {
-            final int bytesRead = session.channel().read(dst);
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": " + bytesRead + " bytes read");
-            }
-            if (bytesRead > 0 && wirelog.isEnabled()) {
-                final ByteBuffer b = dst.duplicate();
-                final int p = b.position();
-                b.limit(p);
-                b.position(p - bytesRead);
-                wirelog.input(b);
-            }
-            return bytesRead;
-        }
-
-        @Override
-        public int write(final ByteBuffer src) throws IOException {
-            final int byteWritten = session.channel().write(src);
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": " + byteWritten + " bytes written");
-            }
-            if (byteWritten > 0 && wirelog.isEnabled()) {
-                final ByteBuffer b = src.duplicate();
-                final int p = b.position();
-                b.limit(p);
-                b.position(p - byteWritten);
-                wirelog.output(b);
-            }
-            return byteWritten;
-        }
-
-        @Override
-        public void close() throws IOException {
-            if (log.isDebugEnabled()) {
-                log.debug(id + " " + session + ": Channel close");
-            }
-            session.channel().close();
-        }
-
-        @Override
-        public boolean isOpen() {
-            return session.channel().isOpen();
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingInputStream.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingInputStream.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingInputStream.java
deleted file mode 100644
index 018fae6..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingInputStream.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-class LoggingInputStream extends InputStream {
-
-    private final InputStream in;
-    private final Wire wire;
-
-    public LoggingInputStream(final InputStream in, final Wire wire) {
-        super();
-        this.in = in;
-        this.wire = wire;
-    }
-
-    @Override
-    public int read() throws IOException {
-        try {
-            final int b = in.read();
-            if (b == -1) {
-                wire.input("end of stream");
-            } else {
-                wire.input(b);
-            }
-            return b;
-        } catch (final IOException ex) {
-            wire.input("[read] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public int read(final byte[] b) throws IOException {
-        try {
-            final int bytesRead = in.read(b);
-            if (bytesRead == -1) {
-                wire.input("end of stream");
-            } else if (bytesRead > 0) {
-                wire.input(b, 0, bytesRead);
-            }
-            return bytesRead;
-        } catch (final IOException ex) {
-            wire.input("[read] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public int read(final byte[] b, final int off, final int len) throws IOException {
-        try {
-            final int bytesRead = in.read(b, off, len);
-            if (bytesRead == -1) {
-                wire.input("end of stream");
-            } else if (bytesRead > 0) {
-                wire.input(b, off, bytesRead);
-            }
-            return bytesRead;
-        } catch (final IOException ex) {
-            wire.input("[read] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public long skip(final long n) throws IOException {
-        try {
-            return super.skip(n);
-        } catch (final IOException ex) {
-            wire.input("[skip] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public int available() throws IOException {
-        try {
-            return in.available();
-        } catch (final IOException ex) {
-            wire.input("[available] I/O error : " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public void mark(final int readlimit) {
-        super.mark(readlimit);
-    }
-
-    @Override
-    public void reset() throws IOException {
-        super.reset();
-    }
-
-    @Override
-    public boolean markSupported() {
-        return false;
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            in.close();
-        } catch (final IOException ex) {
-            wire.input("[close] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingOutputStream.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingOutputStream.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingOutputStream.java
deleted file mode 100644
index ec82d1f..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingOutputStream.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Internal class.
- *
- * @since 4.3
- */
-class LoggingOutputStream extends OutputStream {
-
-    private final OutputStream out;
-    private final Wire wire;
-
-    public LoggingOutputStream(final OutputStream out, final Wire wire) {
-        super();
-        this.out = out;
-        this.wire = wire;
-    }
-
-    @Override
-    public void write(final int b) throws IOException {
-        try {
-            out.write(b);
-            wire.output(b);
-        } catch (final IOException ex) {
-            wire.output("[write] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public void write(final byte[] b) throws IOException {
-        try {
-            wire.output(b);
-            out.write(b);
-        } catch (final IOException ex) {
-            wire.output("[write] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public void write(final byte[] b, final int off, final int len) throws IOException {
-        try {
-            wire.output(b, off, len);
-            out.write(b, off, len);
-        } catch (final IOException ex) {
-            wire.output("[write] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public void flush() throws IOException {
-        try {
-            out.flush();
-        } catch (final IOException ex) {
-            wire.output("[flush] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            out.close();
-        } catch (final IOException ex) {
-            wire.output("[close] I/O error: " + ex.getMessage());
-            throw ex;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingSocketHolder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingSocketHolder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingSocketHolder.java
deleted file mode 100644
index ddde402..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/LoggingSocketHolder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-import org.apache.hc.core5.http.impl.io.SocketHolder;
-import org.apache.logging.log4j.Logger;
-
-public class LoggingSocketHolder extends SocketHolder {
-
-    private final Wire wire;
-
-    public LoggingSocketHolder(final Socket socket, final String id, final Logger log) {
-        super(socket);
-        this.wire = new Wire(log, id);
-    }
-
-    @Override
-    protected InputStream getInputStream(final Socket socket) throws IOException {
-        return new LoggingInputStream(super.getInputStream(socket), wire);
-    }
-
-    @Override
-    protected OutputStream getOutputStream(final Socket socket) throws IOException {
-        return new LoggingOutputStream(super.getOutputStream(socket), wire);
-    }
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
deleted file mode 100644
index 8bd9e4f..0000000
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/logging/Wire.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.http.impl.logging;
-
-import java.nio.ByteBuffer;
-
-import org.apache.hc.core5.util.Args;
-import org.apache.logging.log4j.Logger;
-
-class Wire {
-
-    private static final int MAX_STRING_BUILDER_SIZE = 2048;
-
-    private static final ThreadLocal<StringBuilder> threadLocal = new ThreadLocal<>();
-
-    /**
-     * Returns a {@code StringBuilder} that this Layout implementation can use to write the formatted log event to.
-     *
-     * @return a {@code StringBuilder}
-     */
-    private static StringBuilder getStringBuilder() {
-        StringBuilder result = threadLocal.get();
-        if (result == null) {
-            result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
-            threadLocal.set(result);
-        }
-        // TODO Delegate to Log4j's 2.9 StringBuilds.trimToMaxSize() when it is released.
-        trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
-        result.setLength(0);
-        return result;
-    }
-
-    /**
-     * Ensures that the char[] array of the specified StringBuilder does not exceed the specified number of characters.
-     * This method is useful to ensure that excessively long char[] arrays are not kept in memory forever.
-     *
-     * @param stringBuilder the StringBuilder to check
-     * @param maxSize the maximum number of characters the StringBuilder is allowed to have
-     */
-    // TODO Delete wheb Log4j's 2.9 (see #trimToMaxSize(StringBuild))
-    private static void trimToMaxSize(final StringBuilder stringBuilder, final int maxSize) {
-        if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
-            stringBuilder.setLength(maxSize);
-            stringBuilder.trimToSize();
-        }
-    }
-
-    private final Logger log;
-    private final String id;
-
-    Wire(final Logger log, final String id) {
-        super();
-        this.log = log;
-        this.id = id;
-    }
-
-    private void wire(final String header, final byte[] b, final int pos, final int off) {
-        final StringBuilder buffer = getStringBuilder();
-        for (int i = 0; i < off; i++) {
-            final int ch = b[pos + i];
-            if (ch == 13) {
-                buffer.append("[\\r]");
-            } else if (ch == 10) {
-                    buffer.append("[\\n]\"");
-                    buffer.insert(0, "\"");
-                    buffer.insert(0, header);
-                    this.log.debug(this.id + " " + buffer.toString());
-                    buffer.setLength(0);
-            } else if ((ch < 32) || (ch > 127)) {
-                buffer.append("[0x");
-                buffer.append(Integer.toHexString(ch));
-                buffer.append("]");
-            } else {
-                buffer.append((char) ch);
-            }
-        }
-        if (buffer.length() > 0) {
-            buffer.append('\"');
-            buffer.insert(0, '\"');
-            buffer.insert(0, header);
-            this.log.debug(this.id + " " + buffer.toString());
-        }
-    }
-
-
-    public boolean isEnabled() {
-        return this.log.isDebugEnabled();
-    }
-
-    public void output(final byte[] b, final int pos, final int off) {
-        Args.notNull(b, "Output");
-        wire(">> ", b, pos, off);
-    }
-
-    public void input(final byte[] b, final int pos, final int off) {
-        Args.notNull(b, "Input");
-        wire("<< ", b, pos, off);
-    }
-
-    public void output(final byte[] b) {
-        Args.notNull(b, "Output");
-        output(b, 0, b.length);
-    }
-
-    public void input(final byte[] b) {
-        Args.notNull(b, "Input");
-        input(b, 0, b.length);
-    }
-
-    public void output(final int b) {
-        output(new byte[] {(byte) b});
-    }
-
-    public void input(final int b) {
-        input(new byte[] {(byte) b});
-    }
-
-    public void output(final String s) {
-        Args.notNull(s, "Output");
-        output(s.getBytes());
-    }
-
-    public void input(final String s) {
-        Args.notNull(s, "Input");
-        input(s.getBytes());
-    }
-
-    public void output(final ByteBuffer b) {
-        Args.notNull(b, "Output");
-        if (b.hasArray()) {
-            output(b.array(), b.arrayOffset() + b.position(), b.remaining());
-        } else {
-            final byte[] tmp = new byte[b.remaining()];
-            b.get(tmp);
-            output(tmp);
-        }
-    }
-
-    public void input(final ByteBuffer b) {
-        Args.notNull(b, "Input");
-        if (b.hasArray()) {
-            input(b.array(), b.arrayOffset() + b.position(), b.remaining());
-        } else {
-            final byte[] tmp = new byte[b.remaining()];
-            b.get(tmp);
-            input(tmp);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
index 59d37bb..93ce8eb 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
@@ -58,7 +58,6 @@ import org.apache.hc.core5.http2.nio.command.PingCommand;
 import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.pool.ConnPoolControl;
-import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.PoolEntry;
 import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.pool.PoolStats;
@@ -106,10 +105,9 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
             final SchemePortResolver schemePortResolver,
             final DnsResolver dnsResolver,
             final TimeValue timeToLive,
-            final PoolReusePolicy poolReusePolicy,
-            final ConnPoolListener<HttpRoute> connPoolListener) {
+            final PoolReusePolicy poolReusePolicy) {
         this.connectionOperator = new AsyncClientConnectionOperator(schemePortResolver, dnsResolver, tlsStrategyLookup);
-        this.pool = new StrictConnPool<>(20, 50, timeToLive, poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, connPoolListener);
+        this.pool = new StrictConnPool<>(20, 50, timeToLive, poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, null);
         this.closed = new AtomicBoolean(false);
     }
 
@@ -400,7 +398,7 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
 
         InternalConnectionEndpoint(final PoolEntry<HttpRoute, ManagedAsyncClientConnection> poolEntry) {
             this.poolEntryRef = new AtomicReference<>(poolEntry);
-            this.id = "ep-" + Long.toHexString(COUNT.incrementAndGet());
+            this.id = String.format("ep-%08X", COUNT.getAndIncrement());
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/e8f72b7c/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
index 9a840ad..ed2e42d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManagerBuilder.java
@@ -31,12 +31,10 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 
 import org.apache.hc.client5.http.DnsResolver;
-import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.SchemePortResolver;
 import org.apache.hc.client5.http.ssl.H2TlsStrategy;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
-import org.apache.hc.core5.pool.ConnPoolListener;
 import org.apache.hc.core5.pool.PoolReusePolicy;
 import org.apache.hc.core5.util.TimeValue;
 
@@ -72,7 +70,6 @@ public class PoolingAsyncClientConnectionManagerBuilder {
     private SchemePortResolver schemePortResolver;
     private DnsResolver dnsResolver;
     private PoolReusePolicy poolReusePolicy;
-    private ConnPoolListener<HttpRoute> connPoolListener;
 
     private boolean systemProperties;
 
@@ -124,14 +121,6 @@ public class PoolingAsyncClientConnectionManagerBuilder {
     }
 
     /**
-     * Assigns {@link ConnPoolListener} instance.
-     */
-    public final PoolingAsyncClientConnectionManagerBuilder setConnPoolListener(final ConnPoolListener<HttpRoute> connPoolListener) {
-        this.connPoolListener = connPoolListener;
-        return this;
-    }
-
-    /**
      * Assigns maximum total connection value.
      */
     public final PoolingAsyncClientConnectionManagerBuilder setMaxConnTotal(final int maxConnTotal) {
@@ -184,8 +173,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
                 schemePortResolver,
                 dnsResolver,
                 timeToLive,
-                poolReusePolicy,
-                connPoolListener);
+                poolReusePolicy);
         poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
         if (maxConnTotal > 0) {
             poolingmgr.setMaxTotal(maxConnTotal);


[4/6] httpcomponents-client git commit: Upgraded HttpCore to version 5.0-alpha4

Posted by ol...@apache.org.
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
index 7521f11..0ab7b88 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
@@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
@@ -37,6 +38,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.hc.client5.http.auth.AuthCache;
 import org.apache.hc.client5.http.auth.AuthChallenge;
 import org.apache.hc.client5.http.auth.AuthScheme;
+import org.apache.hc.client5.http.auth.AuthSchemeProvider;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.ChallengeType;
 import org.apache.hc.client5.http.auth.Credentials;
@@ -45,17 +47,21 @@ import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
 import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
 import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
 import org.apache.hc.client5.http.impl.protocol.DefaultAuthenticationStrategy;
 import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.sync.CloseableHttpResponse;
 import org.apache.hc.client5.http.protocol.ClientProtocolException;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.protocol.NonRepeatableRequestException;
 import org.apache.hc.client5.http.sync.methods.HttpGet;
 import org.apache.hc.client5.http.sync.methods.HttpPost;
 import org.apache.hc.client5.http.sync.methods.HttpPut;
-import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
-import org.apache.hc.client5.testing.auth.RequestBasicAuth;
-import org.apache.hc.client5.testing.auth.ResponseBasicUnauthorized;
+import org.apache.hc.client5.testing.BasicTestAuthenticator;
+import org.apache.hc.client5.testing.auth.Authenticator;
+import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
+import org.apache.hc.client5.testing.classic.EchoHandler;
+import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.EndpointDetails;
@@ -65,18 +71,19 @@ import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.io.HttpExpectationVerifier;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicHeader;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.net.URIAuthority;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -84,56 +91,19 @@ import org.junit.Test;
  */
 public class TestClientAuthentication extends LocalServerTestBase {
 
-    @Before @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-            .add(new RequestBasicAuth())
-            .add(new ResponseBasicUnauthorized()).build();
-        this.serverBootstrap.setHttpProcessor(httpproc);
-    }
-
-    static class AuthHandler implements HttpRequestHandler {
+    public HttpHost start(final Authenticator authenticator) throws IOException {
+        return super.start(null, new Decorator<HttpServerRequestHandler>() {
 
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final String creds = (String) context.getAttribute("creds");
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                response.setEntity(entity);
+            @Override
+            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+                return new AuthenticatingDecorator(requestHandler, authenticator);
             }
-        }
 
+        });
     }
 
-    static class AuthExpectationVerifier implements HttpExpectationVerifier {
-
-        private final BasicAuthTokenExtractor authTokenExtractor;
-
-        public AuthExpectationVerifier() {
-            super();
-            this.authTokenExtractor = new BasicAuthTokenExtractor();
-        }
-
-        @Override
-        public void verify(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException {
-            final String creds = this.authTokenExtractor.extract(request);
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response.setCode(HttpStatus.SC_CONTINUE);
-            }
-        }
-
+    public HttpHost start() throws IOException {
+        return start(new BasicTestAuthenticator("test:test", "test realm"));
     }
 
     static class TestCredentialsProvider implements CredentialsProvider {
@@ -160,8 +130,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationNoCreds() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
@@ -181,8 +150,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationFailure() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
@@ -203,8 +171,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpGet httpget = new HttpGet("/");
         final HttpClientContext context = HttpClientContext.create();
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -225,13 +192,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-            .add(new RequestBasicAuth())
-            .add(new ResponseBasicUnauthorized()).build();
-        this.serverBootstrap.setHttpProcessor(httpproc)
-            .setExpectationVerifier(new AuthExpectationVerifier())
-            .registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
         final RequestConfig config = RequestConfig.custom()
@@ -256,11 +217,10 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
-        final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build();
+        final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(false).build();
         final HttpPut httpput = new HttpPut("/");
         httpput.setConfig(config);
         httpput.setEntity(new InputStreamEntity(
@@ -286,8 +246,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
         final HttpPost httppost = new HttpPost("/");
@@ -310,8 +269,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
 
         final HttpPost httppost = new HttpPost("/");
@@ -362,8 +320,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testBasicAuthenticationCredentialsCaching() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
         this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
 
@@ -392,43 +349,34 @@ public class TestClientAuthentication extends LocalServerTestBase {
         Assert.assertEquals(1, authStrategy.getCount());
     }
 
-    static class RealmAuthHandler implements HttpRequestHandler {
-
-        final String realm;
-        final String realmCreds;
-
-        public RealmAuthHandler(final String realm, final String realmCreds) {
-            this.realm = realm;
-            this.realmCreds = realmCreds;
-        }
-
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final String givenCreds = (String) context.getAttribute("creds");
-            if (givenCreds == null || !givenCreds.equals(this.realmCreds)) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"" + this.realm + "\"");
-            } else {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                response.setEntity(entity);
-            }
-        }
-
-    }
-
     @Test
     public void testAuthenticationCredentialsCachingReauthenticationOnDifferentRealm() throws Exception {
-        this.serverBootstrap.registerHandler("/this", new RealmAuthHandler("this realm", "test:this"));
-        this.serverBootstrap.registerHandler("/that", new RealmAuthHandler("that realm", "test:that"));
+        this.server.registerHandler("*", new EchoHandler());
+        final HttpHost target = start(new Authenticator() {
+
+            @Override
+            public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
+                if (requestUri.equals("/this")) {
+                    return "test:this".equals(credentials);
+                } else if (requestUri.equals("/that")) {
+                    return "test:that".equals(credentials);
+                } else {
+                    return "test:test".equals(credentials);
+                }
+            }
 
-        this.server = this.serverBootstrap.create();
-        this.server.start();
+            @Override
+            public String getRealm(final URIAuthority authority, final String requestUri) {
+                if (requestUri.equals("/this")) {
+                    return "this realm";
+                } else if (requestUri.equals("/that")) {
+                    return "that realm";
+                } else {
+                    return "test realm";
+                }
+            }
 
-        final HttpHost target = new HttpHost("localhost", this.server.getLocalPort(), this.scheme.name());
+        });
 
         final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
@@ -472,8 +420,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
         final HttpGet httpget = new HttpGet("http://test:test@" +  target.toHostString() + "/");
 
@@ -487,8 +434,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testAuthenticationUserinfoInRequestFailure() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
+        this.server.registerHandler("*", new EchoHandler());
         final HttpHost target = start();
         final HttpGet httpget = new HttpGet("http://test:all-wrong@" +  target.toHostString() + "/");
 
@@ -500,36 +446,39 @@ public class TestClientAuthentication extends LocalServerTestBase {
         EntityUtils.consume(entity);
     }
 
-    private static class RedirectHandler implements HttpRequestHandler {
-
-        public RedirectHandler() {
-            super();
-        }
-
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
-            final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
-            final String localhost = socketAddress.getHostName();
-            final int port = socketAddress.getPort();
-            response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
-            response.addHeader(new BasicHeader("Location",
-                    "http://test:test@" + localhost + ":" + port + "/"));
-        }
-
-    }
-
     @Test
     public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-        this.serverBootstrap.registerHandler("/thatway", new RedirectHandler());
+        this.server.registerHandler("/*", new EchoHandler());
+        this.server.registerHandler("/thatway", new HttpRequestHandler() {
+
+            @Override
+            public void handle(
+                    final ClassicHttpRequest request,
+                    final ClassicHttpResponse response,
+                    final HttpContext context) throws HttpException, IOException {
+                final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
+                final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
+                final String localhost = socketAddress.getHostName();
+                final int port = socketAddress.getPort();
+                response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
+                response.addHeader(new BasicHeader("Location", "http://test:test@" + localhost + ":" + port + "/secure"));
+            }
 
-        final HttpHost target = start();
+        });
 
-        final HttpGet httpget = new HttpGet("http://" +  target.toHostString() + "/thatway");
+        final HttpHost target = start(new BasicTestAuthenticator("test:test", "test realm") {
+
+            @Override
+            public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
+                if (requestUri.equals("/secure") || requestUri.startsWith("/secure/")) {
+                    return super.authenticate(authority, requestUri, credentials);
+                } else {
+                    return true;
+                }
+            }
+        });
+
+        final HttpGet httpget = new HttpGet("/thatway");
         final HttpClientContext context = HttpClientContext.create();
 
         final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
@@ -539,29 +488,19 @@ public class TestClientAuthentication extends LocalServerTestBase {
         EntityUtils.consume(entity);
     }
 
-    static class CountingAuthHandler implements HttpRequestHandler {
+    static class CountingAuthenticator extends BasicTestAuthenticator {
 
         private final AtomicLong count;
 
-        public CountingAuthHandler() {
-            super();
+        public CountingAuthenticator(final String userToken, final String realm) {
+            super(userToken, realm);
             this.count = new AtomicLong();
         }
 
         @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
+        public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
             this.count.incrementAndGet();
-            final String creds = (String) context.getAttribute("creds");
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                response.setEntity(entity);
-            }
+            return super.authenticate(authority, requestUri, credentials);
         }
 
         public long getCount() {
@@ -572,10 +511,9 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testPreemptiveAuthentication() throws Exception {
-        final CountingAuthHandler requestHandler = new CountingAuthHandler();
-        this.serverBootstrap.registerHandler("*", requestHandler);
-
-        final HttpHost target = start();
+        this.server.registerHandler("*", new EchoHandler());
+        final CountingAuthenticator countingAuthenticator = new CountingAuthenticator("test:test", "test realm");
+        final HttpHost target = start(countingAuthenticator);
 
         final BasicScheme basicScheme = new BasicScheme();
         basicScheme.initPreemptive(new UsernamePasswordCredentials("test", "test".toCharArray()));
@@ -591,15 +529,15 @@ public class TestClientAuthentication extends LocalServerTestBase {
         Assert.assertNotNull(entity1);
         EntityUtils.consume(entity1);
 
-        Assert.assertEquals(1, requestHandler.getCount());
+        Assert.assertEquals(1, countingAuthenticator.getCount());
     }
 
     @Test
     public void testPreemptiveAuthenticationFailure() throws Exception {
-        final CountingAuthHandler requestHandler = new CountingAuthHandler();
-        this.serverBootstrap.registerHandler("*", requestHandler);
+        this.server.registerHandler("*", new EchoHandler());
+        final CountingAuthenticator countingAuthenticator = new CountingAuthenticator("test:test", "test realm");
 
-        final HttpHost target = start();
+        final HttpHost target = start(countingAuthenticator);
 
         final HttpClientContext context = HttpClientContext.create();
         final AuthCache authCache = new BasicAuthCache();
@@ -617,7 +555,7 @@ public class TestClientAuthentication extends LocalServerTestBase {
         Assert.assertNotNull(entity1);
         EntityUtils.consume(entity1);
 
-        Assert.assertEquals(1, requestHandler.getCount());
+        Assert.assertEquals(1, countingAuthenticator.getCount());
     }
 
     static class ProxyAuthHandler implements HttpRequestHandler {
@@ -641,9 +579,9 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
     @Test
     public void testAuthenticationTargetAsProxy() throws Exception {
-        this.serverBootstrap.registerHandler("*", new ProxyAuthHandler());
+        this.server.registerHandler("*", new ProxyAuthHandler());
 
-        final HttpHost target = start();
+        final HttpHost target = super.start();
 
         final HttpClientContext context = HttpClientContext.create();
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
@@ -657,31 +595,27 @@ public class TestClientAuthentication extends LocalServerTestBase {
         EntityUtils.consume(entity);
     }
 
-    static class ClosingAuthHandler implements HttpRequestHandler {
+    @Test
+    public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
+        this.server.registerHandler("*", new EchoHandler());
 
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final String creds = (String) context.getAttribute("creds");
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                response.setEntity(entity);
-                response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-            }
-        }
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<HttpServerRequestHandler>() {
 
-    }
+                    @Override
+                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+                        return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
-    @Test
-    public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new ClosingAuthHandler());
+                            @Override
+                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                                unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                            }
 
-        final HttpHost target = start();
+                        };
+                    }
+
+                });
 
         final HttpClientContext context = HttpClientContext.create();
         final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
@@ -698,4 +632,128 @@ public class TestClientAuthentication extends LocalServerTestBase {
         }
     }
 
+    @Test
+    public void testReauthentication() throws Exception {
+        this.server.registerHandler("*", new EchoHandler());
+
+        final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
+
+            @Override
+            public AuthScheme create(final HttpContext context) {
+                return new BasicScheme() {
+                    private static final long serialVersionUID = 1L;
+
+                    @Override
+                    public String getName() {
+                        return "MyBasic";
+                    }
+
+                };
+            }
+
+        };
+
+        final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
+                new UsernamePasswordCredentials("test", "test".toCharArray()));
+
+        final RequestConfig config = RequestConfig.custom()
+                .setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
+                .build();
+        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
+                .register("MyBasic", myBasicAuthSchemeFactory)
+                .build();
+        this.httpclient = this.clientBuilder
+                .setDefaultAuthSchemeRegistry(authSchemeRegistry)
+                .setDefaultCredentialsProvider(credsProvider)
+                .build();
+
+        final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
+
+            private final AtomicLong count = new AtomicLong(0);
+
+            @Override
+            public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
+                final boolean authenticated = super.authenticate(authority, requestUri, credentials);
+                if (authenticated) {
+                    if (this.count.incrementAndGet() % 4 != 0) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    return false;
+                }
+            }
+        };
+
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<HttpServerRequestHandler>() {
+
+                    @Override
+                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+                        return new AuthenticatingDecorator(requestHandler, authenticator) {
+
+                            @Override
+                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                                unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
+                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
+                            }
+
+                        };
+                    }
+
+                });
+
+        final HttpClientContext context = HttpClientContext.create();
+        for (int i = 0; i < 10; i++) {
+            final HttpGet httpget = new HttpGet("/");
+            httpget.setConfig(config);
+            try (final CloseableHttpResponse response = this.httpclient.execute(target, httpget, context)) {
+                final HttpEntity entity = response.getEntity();
+                Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+                Assert.assertNotNull(entity);
+                EntityUtils.consume(entity);
+            }
+        }
+    }
+
+    @Test
+    public void testAuthenticationFallback() throws Exception {
+        this.server.registerHandler("*", new EchoHandler());
+
+        final HttpHost target = start(
+                HttpProcessors.server(),
+                new Decorator<HttpServerRequestHandler>() {
+
+                    @Override
+                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
+                        return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
+
+                            @Override
+                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
+                            }
+
+                        };
+                    }
+
+                });
+
+        final HttpClientContext context = HttpClientContext.create();
+        final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
+                new UsernamePasswordCredentials("test", "test".toCharArray()));
+        context.setCredentialsProvider(credsProvider);
+        final HttpGet httpget = new HttpGet("/");
+
+        final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
+        final HttpEntity entity = response.getEntity();
+        Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
+        Assert.assertNotNull(entity);
+        EntityUtils.consume(entity);
+        final AuthScope authscope = credsProvider.getAuthScope();
+        Assert.assertNotNull(authscope);
+        Assert.assertEquals("test realm", authscope.getRealm());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFakeNTLM.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFakeNTLM.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFakeNTLM.java
index b205fc4..64da94e 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFakeNTLM.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFakeNTLM.java
@@ -66,7 +66,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
 
     @Test
     public void testNTLMAuthenticationFailure() throws Exception {
-        this.serverBootstrap.registerHandler("*", new NtlmResponseHandler());
+        this.server.registerHandler("*", new NtlmResponseHandler());
 
         final HttpHost target = start();
 
@@ -112,7 +112,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
 
     @Test
     public void testNTLMv1Type2Message() throws Exception {
-        this.serverBootstrap.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
+        this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
                 "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
                 "AGUAcgB2AGUAcgA="));
         final HttpHost target = start();
@@ -136,7 +136,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
 
     @Test
     public void testNTLMv2Type2Message() throws Exception {
-        this.serverBootstrap.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
+        this.server.registerHandler("*", new NtlmType2MessageResponseHandler("TlRMTVNTUAACAA" +
                 "AADAAMADgAAAAzgoriASNFZ4mrze8AAAAAAAAAACQAJABEAAAABgBwFwAAAA9T" +
                 "AGUAcgB2AGUAcgACAAwARABvAG0AYQBpAG4AAQAMAFMAZQByAHYAZQByAAAAAAA="));
         final HttpHost target = start();
@@ -179,7 +179,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
 
     @Test
     public void testNTLMType2MessageOnlyAuthenticationFailure() throws Exception {
-        this.serverBootstrap.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
+        this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
                 "AADAAMADgAAAAzggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
                 "AGUAcgB2AGUAcgA="));
 
@@ -200,7 +200,7 @@ public class TestClientAuthenticationFakeNTLM extends LocalServerTestBase {
 
     @Test
     public void testNTLMType2NonUnicodeMessageOnlyAuthenticationFailure() throws Exception {
-        this.serverBootstrap.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
+        this.server.registerHandler("*", new NtlmType2MessageOnlyResponseHandler("TlRMTVNTUAACAA" +
                 "AABgAGADgAAAAyggLiASNFZ4mrze8AAAAAAAAAAAAAAAAAAAAABgBwFwAAAA9T" +
                 "ZXJ2ZXI="));
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFallBack.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFallBack.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFallBack.java
deleted file mode 100644
index 3bbfe70..0000000
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthenticationFallBack.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.testing.sync;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.hc.client5.http.auth.AuthScope;
-import org.apache.hc.client5.http.auth.Credentials;
-import org.apache.hc.client5.http.auth.CredentialsProvider;
-import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.client5.testing.auth.RequestBasicAuth;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpResponseInterceptor;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestClientAuthenticationFallBack extends LocalServerTestBase {
-
-    public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
-
-        @Override
-        public void process(
-                final HttpResponse response,
-                final EntityDetails entityDetails,
-                final HttpContext context) throws HttpException, IOException {
-            if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"test realm\" invalid");
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test realm\"");
-            }
-        }
-
-    }
-
-    @Before @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-            .add(new RequestBasicAuth())
-            .add(new ResponseBasicUnauthorized()).build();
-        this.serverBootstrap.setHttpProcessor(httpproc);
-    }
-
-    static class AuthHandler implements HttpRequestHandler {
-
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final String creds = (String) context.getAttribute("creds");
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                response.setEntity(entity);
-            }
-        }
-
-    }
-
-    static class TestCredentialsProvider implements CredentialsProvider {
-
-        private final Credentials creds;
-        private AuthScope authscope;
-
-        TestCredentialsProvider(final Credentials creds) {
-            super();
-            this.creds = creds;
-        }
-
-        @Override
-        public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
-            this.authscope = authscope;
-            return this.creds;
-        }
-
-        public AuthScope getAuthScope() {
-            return this.authscope;
-        }
-
-    }
-
-    @Test
-    public void testBasicAuthenticationSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
-        final HttpHost target = start();
-
-        final HttpClientContext context = HttpClientContext.create();
-        final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
-                new UsernamePasswordCredentials("test", "test".toCharArray()));
-        context.setCredentialsProvider(credsProvider);
-        final HttpGet httpget = new HttpGet("/");
-
-        final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
-        final HttpEntity entity = response.getEntity();
-        Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
-        Assert.assertNotNull(entity);
-        EntityUtils.consume(entity);
-        final AuthScope authscope = credsProvider.getAuthScope();
-        Assert.assertNotNull(authscope);
-        Assert.assertEquals("test realm", authscope.getRealm());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientReauthentication.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientReauthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientReauthentication.java
deleted file mode 100644
index 9737ea9..0000000
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientReauthentication.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.testing.sync;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.hc.client5.http.auth.AuthScheme;
-import org.apache.hc.client5.http.auth.AuthSchemeProvider;
-import org.apache.hc.client5.http.auth.AuthScope;
-import org.apache.hc.client5.http.auth.Credentials;
-import org.apache.hc.client5.http.auth.CredentialsProvider;
-import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.config.RequestConfig;
-import org.apache.hc.client5.http.impl.auth.BasicScheme;
-import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
-import org.apache.hc.client5.http.impl.sync.CloseableHttpResponse;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.client5.testing.auth.RequestBasicAuth;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.EntityDetails;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpResponse;
-import org.apache.hc.core5.http.HttpResponseInterceptor;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.config.Registry;
-import org.apache.hc.core5.http.config.RegistryBuilder;
-import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.HttpProcessor;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TestClientReauthentication extends LocalServerTestBase {
-
-    public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
-
-        @Override
-        public void process(
-                final HttpResponse response,
-                final EntityDetails entityDetails,
-                final HttpContext context) throws HttpException, IOException {
-            if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
-            }
-        }
-
-    }
-
-    @Before @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-            .add(new RequestBasicAuth())
-            .add(new ResponseBasicUnauthorized()).build();
-        this.serverBootstrap.setHttpProcessor(httpproc);
-    }
-
-    static class AuthHandler implements HttpRequestHandler {
-
-        private final AtomicLong count = new AtomicLong(0);
-
-        @Override
-        public void handle(
-                final ClassicHttpRequest request,
-                final ClassicHttpResponse response,
-                final HttpContext context) throws HttpException, IOException {
-            final String creds = (String) context.getAttribute("creds");
-            if (creds == null || !creds.equals("test:test")) {
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            } else {
-                // Make client re-authenticate on each fourth request
-                if (this.count.incrementAndGet() % 4 == 0) {
-                    response.setCode(HttpStatus.SC_UNAUTHORIZED);
-                } else {
-                    response.setCode(HttpStatus.SC_OK);
-                    final StringEntity entity = new StringEntity("success", StandardCharsets.US_ASCII);
-                    response.setEntity(entity);
-                }
-            }
-        }
-
-    }
-
-    static class TestCredentialsProvider implements CredentialsProvider {
-
-        private final Credentials creds;
-        private AuthScope authscope;
-
-        TestCredentialsProvider(final Credentials creds) {
-            super();
-            this.creds = creds;
-        }
-
-        @Override
-        public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
-            this.authscope = authscope;
-            return this.creds;
-        }
-
-    }
-
-    @Test
-    public void testBasicAuthenticationSuccess() throws Exception {
-        this.serverBootstrap.registerHandler("*", new AuthHandler());
-
-        final BasicSchemeFactory myBasicAuthSchemeFactory = new BasicSchemeFactory() {
-
-            @Override
-            public AuthScheme create(final HttpContext context) {
-                return new BasicScheme() {
-                    private static final long serialVersionUID = 1L;
-
-                    @Override
-                    public String getName() {
-                        return "MyBasic";
-                    }
-
-                };
-            }
-
-        };
-
-        final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
-                new UsernamePasswordCredentials("test", "test".toCharArray()));
-
-        final RequestConfig config = RequestConfig.custom()
-            .setTargetPreferredAuthSchemes(Arrays.asList("MyBasic"))
-            .build();
-        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
-            .register("MyBasic", myBasicAuthSchemeFactory)
-            .build();
-        this.httpclient = this.clientBuilder
-            .setDefaultAuthSchemeRegistry(authSchemeRegistry)
-            .setDefaultCredentialsProvider(credsProvider)
-            .build();
-
-        final HttpHost target = start();
-
-        final HttpClientContext context = HttpClientContext.create();
-        for (int i = 0; i < 10; i++) {
-            final HttpGet httpget = new HttpGet("/");
-            httpget.setConfig(config);
-            try (final CloseableHttpResponse response = this.httpclient.execute(target, httpget, context)) {
-                final HttpEntity entity = response.getEntity();
-                Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
-                Assert.assertNotNull(entity);
-                EntityUtils.consume(entity);
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
index 02741fd..c715248 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
@@ -110,7 +110,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
     @Test
     public void testAutoGeneratedHeaders() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
 
@@ -163,7 +163,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
     @Test(expected=ClientProtocolException.class)
     public void testNonRepeatableEntity() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
 
@@ -206,7 +206,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
     @Test
     public void testNonCompliantURI() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         final HttpHost target = start();
 
@@ -224,7 +224,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
     @Test
     public void testRelativeRequestURIWithFragment() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         final HttpHost target = start();
 
@@ -241,7 +241,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
 
     @Test
     public void testAbsoluteRequestURIWithFragment() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
 
         final HttpHost target = start();
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionAutoRelease.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionAutoRelease.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionAutoRelease.java
deleted file mode 100644
index 17f25fa..0000000
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionAutoRelease.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * ====================================================================
- * 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.hc.client5.testing.sync;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.hc.client5.http.HttpRoute;
-import org.apache.hc.client5.http.io.ConnectionEndpoint;
-import org.apache.hc.client5.http.io.LeaseRequest;
-import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.config.CharCodingConfig;
-import org.apache.hc.core5.http.config.H1Config;
-import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
-import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnectionFactory;
-import org.apache.hc.core5.http.io.SessionOutputBuffer;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.util.TimeValue;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestConnectionAutoRelease extends LocalServerTestBase {
-
-    @Test
-    public void testReleaseOnEntityConsumeContent() throws Exception {
-        this.connManager.setDefaultMaxPerRoute(1);
-        this.connManager.setMaxTotal(1);
-
-        // Zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        final HttpHost target = start();
-        // Get some random data
-        final HttpGet httpget = new HttpGet("/random/20000");
-        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
-
-        final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
-        try {
-            connreq1.get(250, TimeUnit.MILLISECONDS);
-            Assert.fail("ConnectionPoolTimeoutException should have been thrown");
-        } catch (final TimeoutException expected) {
-        }
-
-        final HttpEntity e = response.getEntity();
-        Assert.assertNotNull(e);
-        EntityUtils.consume(e);
-
-        // Expect one connection in the pool
-        Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
-
-        // Make sure one connection is available
-        final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
-        final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
-
-        this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
-    }
-
-    @Test
-    public void testReleaseOnEntityWriteTo() throws Exception {
-        this.connManager.setDefaultMaxPerRoute(1);
-        this.connManager.setMaxTotal(1);
-
-        // Zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        final HttpHost target = start();
-        // Get some random data
-        final HttpGet httpget = new HttpGet("/random/20000");
-        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
-
-        final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
-        try {
-            connreq1.get(250, TimeUnit.MILLISECONDS);
-            Assert.fail("ConnectionPoolTimeoutException should have been thrown");
-        } catch (final TimeoutException expected) {
-        }
-
-        final HttpEntity e = response.getEntity();
-        Assert.assertNotNull(e);
-        final ByteArrayOutputStream outsteam = new ByteArrayOutputStream();
-        e.writeTo(outsteam);
-
-        // Expect one connection in the pool
-        Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
-
-        // Make sure one connection is available
-        final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
-        final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
-
-        this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
-    }
-
-    @Test
-    public void testReleaseOnAbort() throws Exception {
-        this.connManager.setDefaultMaxPerRoute(1);
-        this.connManager.setMaxTotal(1);
-
-        // Zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        final HttpHost target = start();
-
-        // Get some random data
-        final HttpGet httpget = new HttpGet("/random/20000");
-        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
-
-        final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
-        try {
-            connreq1.get(250, TimeUnit.MILLISECONDS);
-            Assert.fail("ConnectionPoolTimeoutException should have been thrown");
-        } catch (final TimeoutException expected) {
-        }
-
-        final HttpEntity e = response.getEntity();
-        Assert.assertNotNull(e);
-        httpget.abort();
-
-        // Expect zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        // Make sure one connection is available
-        final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
-        final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
-
-        this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
-    }
-
-    @Test
-    public void testReleaseOnIOException() throws Exception {
-        serverBootstrap.setConnectionFactory(new DefaultBHttpServerConnectionFactory(null, H1Config.DEFAULT, CharCodingConfig.DEFAULT) {
-
-            @Override
-            public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException {
-                final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(null, H1Config.DEFAULT) {
-
-                    @Override
-                    protected OutputStream createContentOutputStream(
-                            final long len,
-                            final SessionOutputBuffer buffer,
-                            final OutputStream outputStream,
-                            final Supplier<List<? extends Header>> trailers) {
-                        try {
-                            buffer.flush(outputStream);
-                            outputStream.close();
-                        } catch (final IOException ignore) {
-                        }
-                        return super.createContentOutputStream(len, buffer, outputStream, trailers);
-                    }
-                };
-                conn.bind(socket);
-                return conn;
-            }
-        });
-
-        this.connManager.setDefaultMaxPerRoute(1);
-        this.connManager.setMaxTotal(1);
-
-        // Zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        final HttpHost target = start();
-
-        // Get some random data
-        final HttpGet httpget = new HttpGet("/random/1024");
-        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
-
-        final LeaseRequest connreq1 = this.connManager.lease(new HttpRoute(target), null);
-        try {
-            connreq1.get(250, TimeUnit.MILLISECONDS);
-            Assert.fail("ConnectionPoolTimeoutException should have been thrown");
-        } catch (final TimeoutException expected) {
-        }
-
-        final HttpEntity e = response.getEntity();
-        Assert.assertNotNull(e);
-        // Read the content
-        try {
-            EntityUtils.toByteArray(e);
-            Assert.fail("IOException should have been thrown");
-        } catch (final IOException expected) {
-
-        }
-
-        // Expect zero connections in the pool
-        Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
-
-        // Make sure one connection is available
-        final LeaseRequest connreq2 = this.connManager.lease(new HttpRoute(target), null);
-        final ConnectionEndpoint endpoint = connreq2.get(250, TimeUnit.MILLISECONDS);
-
-        this.connManager.release(endpoint, null, TimeValue.NEG_ONE_MILLISECONDS);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
index 9e1d625..b3f04fa 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestConnectionReuse.java
@@ -32,7 +32,6 @@ import java.net.URI;
 
 import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
 import org.apache.hc.client5.http.sync.methods.HttpGet;
-import org.apache.hc.client5.testing.classic.RandomHandler;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
@@ -53,11 +52,6 @@ public class TestConnectionReuse extends LocalServerTestBase {
 
     @Test
     public void testReuseOfPersistentConnections() throws Exception {
-        final HttpProcessor httpproc = HttpProcessors.customServer(null).build();
-
-        this.serverBootstrap.setHttpProcessor(httpproc)
-                .registerHandler("/random/*", new RandomHandler());
-
         this.connManager.setMaxTotal(5);
         this.connManager.setDefaultMaxPerRoute(5);
 
@@ -101,16 +95,13 @@ public class TestConnectionReuse extends LocalServerTestBase {
 
     @Test
     public void testReuseOfClosedConnections() throws Exception {
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-                .add(new AlwaysCloseConn()).build();
-
-        this.serverBootstrap.setHttpProcessor(httpproc)
-                .registerHandler("/random/*", new RandomHandler());
-
         this.connManager.setMaxTotal(5);
         this.connManager.setDefaultMaxPerRoute(5);
 
-        final HttpHost target = start();
+        final HttpProcessor httpproc = HttpProcessors.customServer(null)
+                .add(new AlwaysCloseConn())
+                .build();
+        final HttpHost target = start(httpproc, null);
 
         final WorkerThread[] workers = new WorkerThread[10];
         for (int i = 0; i < workers.length; i++) {
@@ -138,11 +129,6 @@ public class TestConnectionReuse extends LocalServerTestBase {
 
     @Test
     public void testReuseOfAbortedConnections() throws Exception {
-        final HttpProcessor httpproc = HttpProcessors.customServer(null).build();
-
-        this.serverBootstrap.setHttpProcessor(httpproc)
-                .registerHandler("/random/*", new RandomHandler());
-
         this.connManager.setMaxTotal(5);
         this.connManager.setDefaultMaxPerRoute(5);
 
@@ -174,16 +160,13 @@ public class TestConnectionReuse extends LocalServerTestBase {
 
     @Test
     public void testKeepAliveHeaderRespected() throws Exception {
-        final HttpProcessor httpproc = HttpProcessors.customServer(null)
-                .add(new ResponseKeepAlive()).build();
-
-        this.serverBootstrap.setHttpProcessor(httpproc)
-                .registerHandler("/random/*", new RandomHandler());
-
         this.connManager.setMaxTotal(1);
         this.connManager.setDefaultMaxPerRoute(1);
 
-        final HttpHost target = start();
+        final HttpProcessor httpproc = HttpProcessors.customServer(null)
+                .add(new ResponseKeepAlive())
+                .build();
+        final HttpHost target = start(httpproc, null);
 
         ClassicHttpResponse response = this.httpclient.execute(target, new HttpGet("/random/2000"));
         EntityUtils.consume(response.getEntity());

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
index 19f33c7..35b22bd 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestContentCodings.java
@@ -41,7 +41,7 @@ import java.util.concurrent.Executors;
 import java.util.zip.Deflater;
 import java.util.zip.GZIPOutputStream;
 
-import org.apache.hc.client5.http.impl.sync.BasicResponseHandler;
+import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
 import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
 import org.apache.hc.client5.http.sync.methods.HttpGet;
 import org.apache.hc.core5.http.ClassicHttpRequest;
@@ -75,7 +75,7 @@ public class TestContentCodings extends LocalServerTestBase {
      */
     @Test
     public void testResponseWithNoContent() throws Exception {
-        this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", new HttpRequestHandler() {
 
             /**
              * {@inheritDoc}
@@ -107,7 +107,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testDeflateSupportForServerReturningRfc1950Stream() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
+        this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
 
         final HttpHost target = start();
 
@@ -127,7 +127,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testDeflateSupportForServerReturningRfc1951Stream() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
+        this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
 
         final HttpHost target = start();
 
@@ -146,7 +146,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testGzipSupport() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
+        this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
 
         final HttpHost target = start();
 
@@ -166,7 +166,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testThreadSafetyOfContentCodings() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
+        this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
 
         /*
          * Create a load of workers which will access the resource. Half will use the default
@@ -212,7 +212,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testHttpEntityWriteToForGzip() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
+        this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
 
         final HttpHost target = start();
 
@@ -229,7 +229,7 @@ public class TestContentCodings extends LocalServerTestBase {
     public void testHttpEntityWriteToForDeflate() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
+        this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, true));
 
         final HttpHost target = start();
 
@@ -246,12 +246,12 @@ public class TestContentCodings extends LocalServerTestBase {
     public void gzipResponsesWorkWithBasicResponseHandler() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createGzipEncodingRequestHandler(entityText));
+        this.server.registerHandler("*", createGzipEncodingRequestHandler(entityText));
 
         final HttpHost target = start();
 
         final HttpGet request = new HttpGet("/some-resource");
-        final String response = this.httpclient.execute(target, request, new BasicResponseHandler());
+        final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
         Assert.assertEquals("The entity text is correctly transported", entityText, response);
     }
 
@@ -259,12 +259,12 @@ public class TestContentCodings extends LocalServerTestBase {
     public void deflateResponsesWorkWithBasicResponseHandler() throws Exception {
         final String entityText = "Hello, this is some plain text coming back.";
 
-        this.serverBootstrap.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
+        this.server.registerHandler("*", createDeflateEncodingRequestHandler(entityText, false));
 
         final HttpHost target = start();
 
         final HttpGet request = new HttpGet("/some-resource");
-        final String response = this.httpclient.execute(target, request, new BasicResponseHandler());
+        final String response = this.httpclient.execute(target, request, new BasicHttpClientResponseHandler());
         Assert.assertEquals("The entity text is correctly transported", entityText, response);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
index 47199d6..8adbd85 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
@@ -55,7 +55,7 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
 
     @Test
     public void testCookieMatchingWithVirtualHosts() throws Exception {
-        this.serverBootstrap.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandlerVirtual("app.mydomain.fr", "*", new HttpRequestHandler() {
             @Override
             public void handle(
                     final ClassicHttpRequest request,

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
index 6d353b2..e4fd3cb 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
@@ -29,7 +29,9 @@ package org.apache.hc.client5.testing.sync;
 import java.io.IOException;
 import java.net.Socket;
 
+import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.sync.CloseableHttpResponse;
+import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
 import org.apache.hc.client5.http.sync.methods.HttpGet;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
@@ -37,6 +39,8 @@ import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
 import org.apache.hc.core5.http.io.HttpConnectionFactory;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
@@ -46,7 +50,7 @@ import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assert;
 import org.junit.Test;
 
-public class TestMalformedServerResponse extends LocalServerTestBase {
+public class TestMalformedServerResponse {
 
     static class BrokenServerConnection extends DefaultBHttpServerConnection {
 
@@ -85,41 +89,46 @@ public class TestMalformedServerResponse extends LocalServerTestBase {
 
     @Test
     public void testNoContentResponseWithGarbage() throws Exception {
-        this.serverBootstrap.setConnectionFactory(new BrokenServerConnectionFactory());
-        this.serverBootstrap.registerHandler("/nostuff", new HttpRequestHandler() {
+        try (final HttpServer server = ServerBootstrap.bootstrap()
+                .setConnectionFactory(new BrokenServerConnectionFactory())
+                .register("/nostuff", new HttpRequestHandler() {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_NO_CONTENT);
-            }
-
-        });
-        this.serverBootstrap.registerHandler("/stuff", new HttpRequestHandler() {
+                    @Override
+                    public void handle(
+                            final ClassicHttpRequest request,
+                            final ClassicHttpResponse response,
+                            final HttpContext context) throws HttpException, IOException {
+                        response.setCode(HttpStatus.SC_NO_CONTENT);
+                    }
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_OK);
-                response.setEntity(new StringEntity("Some important stuff"));
-            }
+                })
+                .register("/stuff", new HttpRequestHandler() {
 
-        });
+                    @Override
+                    public void handle(
+                            final ClassicHttpRequest request,
+                            final ClassicHttpResponse response,
+                            final HttpContext context) throws HttpException, IOException {
+                        response.setCode(HttpStatus.SC_OK);
+                        response.setEntity(new StringEntity("Some important stuff"));
+                    }
 
-        final HttpHost target = start();
-        final HttpGet get1 = new HttpGet("/nostuff");
-        try (CloseableHttpResponse response1 = this.httpclient.execute(target, get1)) {
-            Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response1.getCode());
-            EntityUtils.consume(response1.getEntity());
-        }
-        final HttpGet get2 = new HttpGet("/stuff");
-        try (CloseableHttpResponse response2 = this.httpclient.execute(target, get2)) {
-            Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
-            EntityUtils.consume(response2.getEntity());
+                })
+                .create()) {
+            server.start();
+            final HttpHost target = new HttpHost("localhost", server.getLocalPort());
+            try (final CloseableHttpClient httpclient = HttpClientBuilder.create().build()) {
+                final HttpGet get1 = new HttpGet("/nostuff");
+                try (final CloseableHttpResponse response1 = httpclient.execute(target, get1)) {
+                    Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response1.getCode());
+                    EntityUtils.consume(response1.getEntity());
+                }
+                final HttpGet get2 = new HttpGet("/stuff");
+                try (final CloseableHttpResponse response2 = httpclient.execute(target, get2)) {
+                    Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
+                    EntityUtils.consume(response2.getEntity());
+                }
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/1eb22180/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMinimalClientRequestExecution.java
----------------------------------------------------------------------
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMinimalClientRequestExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMinimalClientRequestExecution.java
index 1e315c4..61baafa 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMinimalClientRequestExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMinimalClientRequestExecution.java
@@ -72,7 +72,7 @@ public class TestMinimalClientRequestExecution extends LocalServerTestBase {
 
     @Test
     public void testNonCompliantURI() throws Exception {
-        this.serverBootstrap.registerHandler("*", new SimpleService());
+        this.server.registerHandler("*", new SimpleService());
         this.httpclient = HttpClients.createMinimal();
         final HttpHost target = start();