You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by rs...@apache.org on 2018/12/04 19:15:13 UTC

httpcomponents-core git commit: Add `handshakeTimeout` support throughout

Repository: httpcomponents-core
Updated Branches:
  refs/heads/master ae5473024 -> 40cae2275


Add `handshakeTimeout` support throughout


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

Branch: refs/heads/master
Commit: 40cae22755afb99fcdee733fafb7b25ecce36ba5
Parents: ae54730
Author: Ryan Schmitt <rs...@apache.org>
Authored: Mon Dec 3 13:44:20 2018 -0800
Committer: Ryan Schmitt <rs...@apache.org>
Committed: Tue Dec 4 11:14:41 2018 -0800

----------------------------------------------------------------------
 .../ClientHttpProtocolNegotiatorFactory.java    |  9 ++++++--
 .../ServerHttpProtocolNegotiatorFactory.java    |  9 ++++++--
 .../nio/bootstrap/H2RequesterBootstrap.java     | 10 ++++++++-
 .../impl/nio/bootstrap/H2ServerBootstrap.java   | 10 ++++++++-
 .../bootstrap/Http2MultiplexingRequester.java   |  7 ++++--
 .../Http2MultiplexingRequesterBootstrap.java    |  9 +++++++-
 .../hc/core5/http2/nio/pool/H2ConnPool.java     |  6 +++--
 .../http2/ssl/ConscryptClientTlsStrategy.java   |  7 ++++--
 .../http2/ssl/ConscryptServerTlsStrategy.java   |  7 ++++--
 .../hc/core5/http2/ssl/H2ClientTlsStrategy.java |  7 ++++--
 .../hc/core5/http2/ssl/H2ServerTlsStrategy.java |  7 ++++--
 .../InternalClientHttp1EventHandlerFactory.java |  2 +-
 .../InternalClientHttp2EventHandlerFactory.java |  2 +-
 .../InternalServerHttp1EventHandlerFactory.java |  2 +-
 .../InternalServerHttp2EventHandlerFactory.java |  2 +-
 .../impl/bootstrap/AsyncRequesterBootstrap.java |  9 +++++++-
 .../impl/bootstrap/AsyncServerBootstrap.java    | 13 ++++++++++-
 .../nio/ClientHttp1IOEventHandlerFactory.java   |  9 ++++++--
 .../nio/ServerHttp1IOEventHandlerFactory.java   |  9 ++++++--
 .../http/nio/ssl/BasicClientTlsStrategy.java    |  6 +++--
 .../http/nio/ssl/BasicServerTlsStrategy.java    |  6 +++--
 .../hc/core5/http/nio/ssl/TlsStrategy.java      |  7 ++++--
 .../hc/core5/reactor/AbstractIOSessionPool.java | 12 +++++++---
 .../hc/core5/reactor/InternalDataChannel.java   |  5 +++--
 .../reactor/ssl/TransportSecurityLayer.java     |  5 ++++-
 .../reactor/TestAbstractIOSessionPool.java      | 23 ++++++++++++++------
 26 files changed, 152 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
index 90b5ddb..5a86e45 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
@@ -38,6 +38,7 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link ClientHttpProtocolNegotiator} factory.
@@ -52,16 +53,19 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
     private final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory;
     private final HttpVersionPolicy versionPolicy;
     private final TlsStrategy tlsStrategy;
+    private final Timeout handshakeTimeout;
 
     public ClientHttpProtocolNegotiatorFactory(
             final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory,
             final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory,
             final HttpVersionPolicy versionPolicy,
-            final TlsStrategy tlsStrategy) {
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         this.http1StreamHandlerFactory = Args.notNull(http1StreamHandlerFactory, "HTTP/1.1 stream handler factory");
         this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
         this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
         this.tlsStrategy = tlsStrategy;
+        this.handshakeTimeout = handshakeTimeout;
     }
 
     @Override
@@ -74,7 +78,8 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
                         host,
                         ioSession.getLocalAddress(),
                         ioSession.getRemoteAddress(),
-                        attachment);
+                        attachment,
+                        handshakeTimeout);
             }
         }
         return new ClientHttpProtocolNegotiator(

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
index adcefee..0a57aec 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
@@ -36,6 +36,7 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link ServerHttpProtocolNegotiator} factory.
@@ -50,16 +51,19 @@ public class ServerHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
     private final ServerHttp2StreamMultiplexerFactory http2StreamMultiplexerFactory;
     private final HttpVersionPolicy versionPolicy;
     private final TlsStrategy tlsStrategy;
+    private final Timeout handshakeTimeout;
 
     public ServerHttpProtocolNegotiatorFactory(
             final ServerHttp1StreamDuplexerFactory http1StreamDuplexerFactory,
             final ServerHttp2StreamMultiplexerFactory http2StreamMultiplexerFactory,
             final HttpVersionPolicy versionPolicy,
-            final TlsStrategy tlsStrategy) {
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         this.http1StreamDuplexerFactory = Args.notNull(http1StreamDuplexerFactory, "HTTP/1.1 stream handler factory");
         this.http2StreamMultiplexerFactory = Args.notNull(http2StreamMultiplexerFactory, "HTTP/2 stream handler factory");
         this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
         this.tlsStrategy = tlsStrategy;
+        this.handshakeTimeout = handshakeTimeout;
     }
 
     @Override
@@ -70,7 +74,8 @@ public class ServerHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
                     null,
                     ioSession.getLocalAddress(),
                     ioSession.getRemoteAddress(),
-                    attachment != null ? attachment : versionPolicy);
+                    attachment != null ? attachment : versionPolicy,
+                    handshakeTimeout);
         }
         return new ServerHttpProtocolNegotiator(ioSession, http1StreamDuplexerFactory, http2StreamMultiplexerFactory, versionPolicy);
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index ec6ca07..256c8a9 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -63,6 +63,7 @@ import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link Http2AsyncRequester} bootstrap.
@@ -85,6 +86,7 @@ public class H2RequesterBootstrap {
     private PoolReusePolicy poolReusePolicy;
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
+    private Timeout handshakeTimeout;
     private Decorator<IOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http2StreamListener streamListener;
@@ -187,6 +189,11 @@ public class H2RequesterBootstrap {
         return this;
     }
 
+    public final H2RequesterBootstrap setHandshakeTimeout(final Timeout handshakeTimeout) {
+        this.handshakeTimeout = handshakeTimeout;
+        return this;
+    }
+
     /**
      * Assigns {@link IOSession} {@link Decorator} instance.
      */
@@ -304,7 +311,8 @@ public class H2RequesterBootstrap {
                 http1StreamHandlerFactory,
                 http2StreamHandlerFactory,
                 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
-                tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy());
+                tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy(),
+                handshakeTimeout);
         return new Http2AsyncRequester(
                 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
                 ioReactorConfig,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index 5ca3df0..f5c1759 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -71,6 +71,7 @@ import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * HTTP/2 capable {@link HttpAsyncServer} bootstrap.
@@ -90,6 +91,7 @@ public class H2ServerBootstrap {
     private H2Config h2Config;
     private H1Config h1Config;
     private TlsStrategy tlsStrategy;
+    private Timeout handshakeTimeout;
     private Decorator<IOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http2StreamListener http2StreamListener;
@@ -170,6 +172,11 @@ public class H2ServerBootstrap {
         return this;
     }
 
+    public final H2ServerBootstrap setHandshakeTimeout(final Timeout handshakeTimeout) {
+        this.handshakeTimeout = handshakeTimeout;
+        return this;
+    }
+
     /**
      * Assigns {@link IOSession} {@link Decorator} instance.
      */
@@ -414,7 +421,8 @@ public class H2ServerBootstrap {
                 http1StreamHandlerFactory,
                 http2StreamHandlerFactory,
                 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
-                tlsStrategy != null ? tlsStrategy : new H2ServerTlsStrategy(443, 8443));
+                tlsStrategy != null ? tlsStrategy : new H2ServerTlsStrategy(443, 8443),
+                handshakeTimeout);
         return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequester.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequester.java
index f3608a3..1805cd2 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequester.java
@@ -83,6 +83,7 @@ import org.apache.hc.core5.util.Timeout;
 public class Http2MultiplexingRequester extends AsyncRequester{
 
     private final H2ConnPool connPool;
+    private final Timeout handshakeTimeout;
 
     /**
      * Use {@link Http2MultiplexingRequesterBootstrap} to create instances of this class.
@@ -94,10 +95,12 @@ public class Http2MultiplexingRequester extends AsyncRequester{
             final Decorator<IOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Resolver<HttpHost, InetSocketAddress> addressResolver,
-            final TlsStrategy tlsStrategy) {
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener,
                         ShutdownCommand.GRACEFUL_IMMEDIATE_CALLBACK, DefaultAddressResolver.INSTANCE);
         this.connPool = new H2ConnPool(this, addressResolver, tlsStrategy);
+        this.handshakeTimeout = handshakeTimeout;
     }
 
     public void closeIdle(final TimeValue idleTime) {
@@ -158,7 +161,7 @@ public class Http2MultiplexingRequester extends AsyncRequester{
                         throw new ProtocolException("Request authority not specified");
                     }
                     final HttpHost target = new HttpHost(scheme, authority);
-                    connPool.getSession(target, timeout, new FutureCallback<IOSession>() {
+                    connPool.getSession(target, timeout, handshakeTimeout, new FutureCallback<IOSession>() {
 
                         @Override
                         public void completed(final IOSession ioSession) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequesterBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequesterBootstrap.java
index c936247..589210b 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2MultiplexingRequesterBootstrap.java
@@ -52,6 +52,7 @@ import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link Http2MultiplexingRequester} bootstrap.
@@ -67,6 +68,7 @@ public class Http2MultiplexingRequesterBootstrap {
     private CharCodingConfig charCodingConfig;
     private H2Config h2Config;
     private TlsStrategy tlsStrategy;
+    private Timeout handshakeTimeout;
     private boolean strictALPNHandshake;
     private Decorator<IOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
@@ -120,6 +122,10 @@ public class Http2MultiplexingRequesterBootstrap {
         return this;
     }
 
+    public final Http2MultiplexingRequesterBootstrap setHandshakeTimeout(final Timeout handshakeTimeout) {
+        this.handshakeTimeout = handshakeTimeout;
+        return this;
+    }
 
     public final Http2MultiplexingRequesterBootstrap setStrictALPNHandshake(final boolean strictALPNHandshake) {
         this.strictALPNHandshake = strictALPNHandshake;
@@ -212,7 +218,8 @@ public class Http2MultiplexingRequesterBootstrap {
                 ioSessionDecorator,
                 sessionListener,
                 DefaultAddressResolver.INSTANCE,
-                tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy());
+                tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy(),
+                handshakeTimeout);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
index 777dbf6..52431a8 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
@@ -98,6 +98,7 @@ public final class H2ConnPool extends AbstractIOSessionPool<HttpHost> {
     protected Future<IOSession> connectSession(
             final HttpHost namedEndpoint,
             final Timeout requestTimeout,
+            final Timeout handshakeTimeout,
             final FutureCallback<IOSession> callback) {
         final InetSocketAddress remoteAddress = addressResolver.resolve(namedEndpoint);
         return connectionInitiator.connect(namedEndpoint, remoteAddress, null, requestTimeout, null, new FutureCallback<IOSession>() {
@@ -112,7 +113,8 @@ public final class H2ConnPool extends AbstractIOSessionPool<HttpHost> {
                             namedEndpoint,
                             ioSession.getLocalAddress(),
                             ioSession.getRemoteAddress(),
-                            null);
+                            null,
+                            handshakeTimeout);
                     ioSession.setSocketTimeout(requestTimeout);
                 }
                 callback.completed(ioSession);
@@ -156,4 +158,4 @@ public final class H2ConnPool extends AbstractIOSessionPool<HttpHost> {
         callback.execute(true);
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
index 1c701e2..88cf871 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
@@ -39,6 +39,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic client-side implementation of {@link TlsStrategy} that upgrades to TLS for all endpoints
@@ -87,7 +88,8 @@ public class ConscryptClientTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
             tlsSession.startTls(
@@ -95,7 +97,8 @@ public class ConscryptClientTlsStrategy implements TlsStrategy {
                     host,
                     sslBufferMode,
                     ConscryptSupport.initialize(attachment, initializer),
-                    ConscryptSupport.verify(verifier));
+                    ConscryptSupport.verify(verifier),
+                    handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
index 1cea2cb..a93a373 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
@@ -40,6 +40,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic side-side implementation of {@link TlsStrategy} that upgrades to TLS for endpoints
@@ -97,14 +98,16 @@ public class ConscryptServerTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         if (securePortStrategy != null && securePortStrategy.isSecure(localAddress)) {
             tlsSession.startTls(
                     sslContext,
                     host,
                     sslBufferMode,
                     ConscryptSupport.initialize(attachment, initializer),
-                    ConscryptSupport.verify(verifier));
+                    ConscryptSupport.verify(verifier),
+                    handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
index 9d8a306..a003d54 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
@@ -40,6 +40,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic client-side implementation of {@link TlsStrategy} that upgrades to TLS for all endpoints
@@ -92,7 +93,8 @@ public class H2ClientTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
             tlsSession.startTls(
@@ -100,7 +102,8 @@ public class H2ClientTlsStrategy implements TlsStrategy {
                     host,
                     sslBufferMode,
                     H2TlsSupport.enforceRequirements(attachment, initializer),
-                    verifier);
+                    verifier,
+                    handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
index 2c9ef7b..1b1d4a7 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
@@ -41,6 +41,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic side-side implementation of {@link TlsStrategy} that upgrades to TLS for endpoints
@@ -98,14 +99,16 @@ public class H2ServerTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         if (securePortStrategy != null && securePortStrategy.isSecure(localAddress)) {
             tlsSession.startTls(
                     sslContext,
                     host,
                     sslBufferMode,
                     H2TlsSupport.enforceRequirements(attachment, initializer),
-                    verifier);
+                    verifier,
+                    handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp1EventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp1EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp1EventHandlerFactory.java
index 1217e1a..9f74e5d 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp1EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp1EventHandlerFactory.java
@@ -103,7 +103,7 @@ class InternalClientHttp1EventHandlerFactory implements IOEventHandlerFactory {
     @Override
     public IOEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
         if (sslContext != null) {
-            ioSession.startTls(sslContext, null, null ,null, null);
+            ioSession.startTls(sslContext, null, null ,null, null, null);
         }
         final ClientHttp1StreamDuplexer streamDuplexer = createClientHttp1StreamDuplexer(
                 ioSession,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp2EventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp2EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp2EventHandlerFactory.java
index 7ac1466..fc895ea 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp2EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientHttp2EventHandlerFactory.java
@@ -76,7 +76,7 @@ class InternalClientHttp2EventHandlerFactory implements IOEventHandlerFactory {
     @Override
     public IOEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
         if (sslContext != null) {
-            ioSession.startTls(sslContext, null, null ,null, null);
+            ioSession.startTls(sslContext, null, null ,null, null, null);
         }
         final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
                 httpProcessor != null ? httpProcessor : HttpProcessors.client(),

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
index 489296f..2d8900a 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
@@ -111,7 +111,7 @@ class InternalServerHttp1EventHandlerFactory implements IOEventHandlerFactory {
     @Override
     public IOEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
         if (sslContext != null) {
-            ioSession.startTls(sslContext, null, null ,null, null);
+            ioSession.startTls(sslContext, null, null ,null, null, null);
         }
         final ServerHttp1StreamDuplexer streamDuplexer = createServerHttp1StreamDuplexer(
                 ioSession,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp2EventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp2EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp2EventHandlerFactory.java
index 3b3183e..97060a9 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp2EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp2EventHandlerFactory.java
@@ -76,7 +76,7 @@ class InternalServerHttp2EventHandlerFactory implements IOEventHandlerFactory {
     @Override
     public IOEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
         if (sslContext != null) {
-            ioSession.startTls(sslContext, null, null ,null, null);
+            ioSession.startTls(sslContext, null, null ,null, null, null);
         }
         final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
                 httpProcessor != null ? httpProcessor : HttpProcessors.server(),

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
index ae37de0..1432394 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
@@ -69,6 +69,7 @@ public class AsyncRequesterBootstrap {
     private PoolReusePolicy poolReusePolicy;
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
+    private Timeout handshakeTimeout;
     private Decorator<IOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
@@ -161,6 +162,11 @@ public class AsyncRequesterBootstrap {
         return this;
     }
 
+    public final AsyncRequesterBootstrap setTlsHandshakeTimeout(final Timeout handshakeTimeout) {
+        this.handshakeTimeout = handshakeTimeout;
+        return this;
+    }
+
     /**
      * Assigns {@link IOSession} {@link Decorator} instance.
      */
@@ -223,7 +229,8 @@ public class AsyncRequesterBootstrap {
                 streamListener);
         final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttp1IOEventHandlerFactory(
                 streamDuplexerFactory,
-                tlsStrategy != null ? tlsStrategy : new BasicClientTlsStrategy());
+                tlsStrategy != null ? tlsStrategy : new BasicClientTlsStrategy(),
+                handshakeTimeout);
         return new HttpAsyncRequester(
                 ioReactorConfig,
                 ioEventHandlerFactory,

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
index 3cc7d3f..ce74518 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
@@ -64,6 +64,7 @@ import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link HttpAsyncServer} bootstrap.
@@ -82,6 +83,7 @@ public class AsyncServerBootstrap {
     private HttpProcessor httpProcessor;
     private ConnectionReuseStrategy connStrategy;
     private TlsStrategy tlsStrategy;
+    private Timeout handshakeTimeout;
     private Decorator<IOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
@@ -152,6 +154,14 @@ public class AsyncServerBootstrap {
     }
 
     /**
+     * Assigns TLS handshake {@link Timeout}.
+     */
+    public final AsyncServerBootstrap setTlsHandshakeTimeout(final Timeout handshakeTimeout) {
+        this.handshakeTimeout = handshakeTimeout;
+        return this;
+    }
+
+    /**
      * Assigns {@link IOSession} {@link Decorator} instance.
      */
     public final AsyncServerBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
@@ -381,7 +391,8 @@ public class AsyncServerBootstrap {
                 streamListener);
         final IOEventHandlerFactory ioEventHandlerFactory = new ServerHttp1IOEventHandlerFactory(
                 streamHandlerFactory,
-                tlsStrategy);
+                tlsStrategy,
+                handshakeTimeout);
         return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
index c787f21..9c215a7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
@@ -36,6 +36,7 @@ import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link ClientHttp1IOEventHandler} factory.
@@ -47,12 +48,15 @@ public class ClientHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
 
     private final ClientHttp1StreamDuplexerFactory streamDuplexerFactory;
     private final TlsStrategy tlsStrategy;
+    private final Timeout handshakeTimeout;
 
     public ClientHttp1IOEventHandlerFactory(
             final ClientHttp1StreamDuplexerFactory streamDuplexerFactory,
-            final TlsStrategy tlsStrategy) {
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         this.streamDuplexerFactory = Args.notNull(streamDuplexerFactory, "Stream duplexer factory");
         this.tlsStrategy = tlsStrategy;
+        this.handshakeTimeout = handshakeTimeout;
     }
 
     @Override
@@ -65,7 +69,8 @@ public class ClientHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
                         host,
                         ioSession.getLocalAddress(),
                         ioSession.getRemoteAddress(),
-                        attachment);
+                        attachment,
+                        handshakeTimeout);
             }
         }
         return new ClientHttp1IOEventHandler(streamDuplexerFactory.create(ioSession));

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
index 7a47a1d..0da7931 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
@@ -35,6 +35,7 @@ import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * {@link ServerHttp1IOEventHandler} factory.
@@ -46,12 +47,15 @@ public class ServerHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
 
     private final ServerHttp1StreamDuplexerFactory streamDuplexerFactory;
     private final TlsStrategy tlsStrategy;
+    private final Timeout handshakeTimeout;
 
     public ServerHttp1IOEventHandlerFactory(
             final ServerHttp1StreamDuplexerFactory streamDuplexerFactory,
-            final TlsStrategy tlsStrategy) {
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         this.streamDuplexerFactory = Args.notNull(streamDuplexerFactory, "Stream duplexer factory");
         this.tlsStrategy = tlsStrategy;
+        this.handshakeTimeout = handshakeTimeout;
     }
 
     @Override
@@ -63,7 +67,8 @@ public class ServerHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
                     null,
                     ioSession.getLocalAddress(),
                     ioSession.getRemoteAddress(),
-                    attachment);
+                    attachment,
+                    handshakeTimeout);
         } else {
             tlsSecured = false;
         }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
index cd8c73c..9703efd 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
@@ -39,6 +39,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic client-side implementation of {@link TlsStrategy} that upgrades to TLS for all endpoints
@@ -91,10 +92,11 @@ public class BasicClientTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
-            tlsSession.startTls(sslContext, host, sslBufferMode, initializer, verifier);
+            tlsSession.startTls(sslContext, host, sslBufferMode, initializer, verifier, handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
index 7a08d62..7f7ee36 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
@@ -38,6 +38,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Basic side-side implementation of {@link TlsStrategy} that upgrades to TLS for endpoints
@@ -95,9 +96,10 @@ public class BasicServerTlsStrategy implements TlsStrategy {
             final HttpHost host,
             final SocketAddress localAddress,
             final SocketAddress remoteAddress,
-            final Object attachment) {
+            final Object attachment,
+            final Timeout handshakeTimeout) {
         if (securePortStrategy != null && securePortStrategy.isSecure(localAddress)) {
-            tlsSession.startTls(sslContext, host, sslBufferMode, initializer, verifier);
+            tlsSession.startTls(sslContext, host, sslBufferMode, initializer, verifier, handshakeTimeout);
             return true;
         }
         return false;

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
index b3c8636..aa7b488 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
@@ -31,6 +31,7 @@ import java.net.SocketAddress;
 
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * TLS protocol upgrade strategy for non-blocking {@link TransportSecurityLayer} sessions.
@@ -40,13 +41,14 @@ import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 public interface TlsStrategy {
 
     /**
-     * Secures current session layer with LTS security.
+     * Secures current session layer with TLS security.
      *
      * @param sessionLayer the session layer
      * @param host the name of the opposite endpoint when givem or {@code null} otherwise.
      * @param localAddress the address of the local endpoint.
      * @param remoteAddress the address of the remote endpoint.
      * @param attachment arbitrary object passes to the TLS session initialization code.
+     * @param handshakeTimeout the timeout to use while performing the TLS handshake; may be {@code null}.
      * @return {@code true} if the session has been upgraded, {@code false} otherwise.
      */
     boolean upgrade(
@@ -54,6 +56,7 @@ public interface TlsStrategy {
             HttpHost host,
             SocketAddress localAddress,
             SocketAddress remoteAddress,
-            Object attachment);
+            Object attachment,
+            Timeout handshakeTimeout);
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
index 66362ab..229b3b8 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
@@ -66,6 +66,7 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
     protected abstract Future<IOSession> connectSession(
             T namedEndpoint,
             Timeout requestTimeout,
+            final Timeout handshakeTimeout,
             FutureCallback<IOSession> callback);
 
     protected abstract void validateSession(
@@ -123,12 +124,14 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
     public final Future<IOSession> getSession(
             final T endpoint,
             final Timeout requestTimeout,
+            final Timeout handshakeTimeout,
             final FutureCallback<IOSession> callback) {
         Args.notNull(endpoint, "Endpoint");
         Asserts.check(!closed.get(), "Connection pool shut down");
         final ComplexFuture<IOSession> future = new ComplexFuture<>(callback);
         final PoolEntry poolEntry = getPoolEntry(endpoint);
-        getSessionInternal(poolEntry, false, endpoint, requestTimeout, new FutureCallback<IOSession>() {
+        getSessionInternal(poolEntry, false, endpoint, requestTimeout, handshakeTimeout,
+            new FutureCallback<IOSession>() {
 
             @Override
             public void completed(final IOSession ioSession) {
@@ -139,7 +142,8 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
                         if (result) {
                             future.completed(ioSession);
                         } else {
-                            getSessionInternal(poolEntry, true, endpoint, requestTimeout, new FutureCallback<IOSession>() {
+                            getSessionInternal(poolEntry, true, endpoint, requestTimeout, handshakeTimeout,
+                                new FutureCallback<IOSession>() {
 
                                 @Override
                                 public void completed(final IOSession ioSession) {
@@ -182,6 +186,7 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
             final boolean requestNew,
             final T namedEndpoint,
             final Timeout requestTimeout,
+            final Timeout handshakeTimeout,
             final FutureCallback<IOSession> callback) {
         synchronized (poolEntry) {
             if (poolEntry.session != null && requestNew) {
@@ -199,6 +204,7 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
                     poolEntry.sessionFuture = connectSession(
                             namedEndpoint,
                             requestTimeout,
+                            handshakeTimeout,
                             new FutureCallback<IOSession>() {
 
                                 @Override
@@ -297,4 +303,4 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
 
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index 3f2faf6..c8b92fb 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -218,7 +218,8 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
             final NamedEndpoint endpoint,
             final SSLBufferMode sslBufferMode,
             final SSLSessionInitializer initializer,
-            final SSLSessionVerifier verifier) {
+            final SSLSessionVerifier verifier,
+            final Timeout handshakeTimeout) {
         if (!tlsSessionRef.compareAndSet(null, new SSLIOSession(
                 endpoint != null ? endpoint : initialEndpoint,
                 ioSession,
@@ -248,7 +249,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
                     }
 
                 },
-                null))) {
+                handshakeTimeout))) {
             throw new IllegalStateException("TLS already activated");
         }
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
index bc9f0a0..e9add69 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.reactor.ssl;
 import javax.net.ssl.SSLContext;
 
 import org.apache.hc.core5.net.NamedEndpoint;
+import org.apache.hc.core5.util.Timeout;
 
 /**
  * Represents a TLS capable session layer.
@@ -48,13 +49,15 @@ public interface TransportSecurityLayer {
      * @param sslBufferMode SSL buffer management mode.
      * @param initializer SSL session initialization callback.
      * @param verifier SSL session verification callback.
+     * @param handshakeTimeout the timeout to use while performing the TLS handshake; may be {@code null}.
      */
     void startTls(
             SSLContext sslContext,
             NamedEndpoint endpoint,
             SSLBufferMode sslBufferMode,
             SSLSessionInitializer initializer,
-            SSLSessionVerifier verifier) throws UnsupportedOperationException;
+            SSLSessionVerifier verifier,
+            Timeout handshakeTimeout) throws UnsupportedOperationException;
 
     /**
      * Returns details of a fully established TLS session.

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/40cae227/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java b/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
index 267075d..bc7ccc8 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
@@ -76,6 +76,7 @@ public class TestAbstractIOSessionPool {
         Mockito.when(impl.connectSession(
                 ArgumentMatchers.anyString(),
                 ArgumentMatchers.<Timeout>any(),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any())).thenReturn(connectFuture);
 
         Mockito.doAnswer(new Answer() {
@@ -89,7 +90,7 @@ public class TestAbstractIOSessionPool {
 
         }).when(impl).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
 
-        final Future<IOSession> future1 = impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        final Future<IOSession> future1 = impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
         Assert.assertThat(future1, CoreMatchers.notNullValue());
         Assert.assertThat(future1.isDone(), CoreMatchers.equalTo(false));
         Assert.assertThat(impl.getRoutes(), CoreMatchers.hasItem("somehost"));
@@ -97,9 +98,10 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.eq(Timeout.ofSeconds(123L)),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any());
 
-        final Future<IOSession> future2 = impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        final Future<IOSession> future2 = impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
         Assert.assertThat(future2, CoreMatchers.notNullValue());
         Assert.assertThat(future2.isDone(), CoreMatchers.equalTo(false));
         Assert.assertThat(impl.getRoutes(), CoreMatchers.hasItem("somehost"));
@@ -107,6 +109,7 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.<Timeout>any(),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.argThat(new ArgumentMatcher<FutureCallback<IOSession>>() {
 
                     @Override
@@ -125,11 +128,12 @@ public class TestAbstractIOSessionPool {
 
         Mockito.verify(impl, Mockito.times(2)).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
 
-        final Future<IOSession> future3 = impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        final Future<IOSession> future3 = impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
 
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.<Timeout>any(),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any());
 
         Mockito.verify(impl, Mockito.times(3)).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
@@ -144,9 +148,10 @@ public class TestAbstractIOSessionPool {
         Mockito.when(impl.connectSession(
                 ArgumentMatchers.anyString(),
                 ArgumentMatchers.<Timeout>any(),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any())).thenReturn(connectFuture);
 
-        final Future<IOSession> future1 = impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        final Future<IOSession> future1 = impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
         Assert.assertThat(future1, CoreMatchers.notNullValue());
         Assert.assertThat(future1.isDone(), CoreMatchers.equalTo(false));
         Assert.assertThat(impl.getRoutes(), CoreMatchers.hasItem("somehost"));
@@ -154,9 +159,10 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.eq(Timeout.ofSeconds(123L)),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any());
 
-        final Future<IOSession> future2 = impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        final Future<IOSession> future2 = impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
         Assert.assertThat(future2, CoreMatchers.notNullValue());
         Assert.assertThat(future2.isDone(), CoreMatchers.equalTo(false));
         Assert.assertThat(impl.getRoutes(), CoreMatchers.hasItem("somehost"));
@@ -164,6 +170,7 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.<Timeout>any(),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.argThat(new ArgumentMatcher<FutureCallback<IOSession>>() {
 
                     @Override
@@ -262,11 +269,12 @@ public class TestAbstractIOSessionPool {
 
         }).when(impl).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
 
-        impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
 
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.eq(Timeout.ofSeconds(123L)),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any());
     }
 
@@ -278,11 +286,12 @@ public class TestAbstractIOSessionPool {
 
         Mockito.when(ioSession1.isClosed()).thenReturn(true);
 
-        impl.getSession("somehost", Timeout.ofSeconds(123L), null);
+        impl.getSession("somehost", Timeout.ofSeconds(123L), null, null);
 
         Mockito.verify(impl).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.eq(Timeout.ofSeconds(123L)),
+                ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any());
     }