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 2019/09/30 13:09:09 UTC

[httpcomponents-core] branch bug-fixes created (now e326a64)

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a change to branch bug-fixes
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git.


      at e326a64  HTTPCORE-604: async HTTP/1.1 protocol handler must close the i/o session if it cannot be kept alive before passing control to the message exchange hanlder

This branch includes the following new commits:

     new 1186d18  Changed wiring of the I/O session logging decorator; I/O session logging classes marked as internal
     new e326a64  HTTPCORE-604: async HTTP/1.1 protocol handler must close the i/o session if it cannot be kept alive before passing control to the message exchange hanlder

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[httpcomponents-core] 02/02: HTTPCORE-604: async HTTP/1.1 protocol handler must close the i/o session if it cannot be kept alive before passing control to the message exchange hanlder

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch bug-fixes
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit e326a64971573cd9a42dc77d65174a906bad85c0
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Mon Sep 30 14:48:52 2019 +0200

    HTTPCORE-604: async HTTP/1.1 protocol handler must close the i/o session if it cannot be kept alive before passing control to the message exchange hanlder
---
 .../hc/core5/testing/nio/Http1IntegrationTest.java | 68 ++++++++++++++++++++++
 .../testing/nio/Http1ServerAndRequesterTest.java   | 29 +++++++++
 .../http/impl/nio/ClientHttp1StreamHandler.java    |  7 ++-
 3 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index e167c38..e82b566 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -108,6 +108,7 @@ import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
 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.AbstractServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
 import org.apache.hc.core5.http.nio.support.BasicAsyncServerExpectationDecorator;
 import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
@@ -221,6 +222,40 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
     }
 
     @Test
+    public void testSimpleGetConnectionClose() throws Exception {
+        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new SingleLineResponseHandler("Hi there");
+            }
+
+        });
+        final InetSocketAddress serverEndpoint = server.start();
+
+        client.start();
+        final URI requestURI = createRequestURI(serverEndpoint, "/hello");
+        for (int i = 0; i < 5; i++) {
+            final Future<ClientSessionEndpoint> connectFuture = client.connect(
+                    "localhost", serverEndpoint.getPort(), TIMEOUT);
+            try (final ClientSessionEndpoint streamEndpoint = connectFuture.get()) {
+                final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
+                        AsyncRequestBuilder.get(requestURI)
+                                .addHeader(HttpHeaders.CONNECTION, "close")
+                                .build(),
+                        new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+                final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+                Assert.assertNotNull(result);
+                final HttpResponse response1 = result.getHead();
+                final String entity1 = result.getBody();
+                Assert.assertNotNull(response1);
+                Assert.assertEquals(200, response1.getCode());
+                Assert.assertEquals("Hi there", entity1);
+            }
+        }
+    }
+
+    @Test
     public void testSimpleGetIdentityTransfer() throws Exception {
         server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
 
@@ -654,6 +689,39 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
     }
 
     @Test
+    public void testSimpleHeadConnectionClose() throws Exception {
+        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new SingleLineResponseHandler("Hi there");
+            }
+
+        });
+        final InetSocketAddress serverEndpoint = server.start();
+
+        client.start();
+        final URI requestURI = createRequestURI(serverEndpoint, "/hello");
+        for (int i = 0; i < 5; i++) {
+            final Future<ClientSessionEndpoint> connectFuture = client.connect(
+                    "localhost", serverEndpoint.getPort(), TIMEOUT);
+            try (final ClientSessionEndpoint streamEndpoint = connectFuture.get()) {
+                final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
+                        AsyncRequestBuilder.head(requestURI)
+                                .addHeader(HttpHeaders.CONNECTION, "close")
+                                .build(),
+                        new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+                final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+                Assert.assertNotNull(result);
+                final HttpResponse response1 = result.getHead();
+                Assert.assertNotNull(response1);
+                Assert.assertEquals(200, response1.getCode());
+                Assert.assertNull(result.getBody());
+            }
+        }
+    }
+
+    @Test
     public void testHeadPipelined() throws Exception {
         server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
index 04d8f5e..ee2679d 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
@@ -53,6 +53,7 @@ import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.impl.bootstrap.StandardFilters;
+import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.http.nio.AsyncDataConsumer;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
@@ -394,4 +395,32 @@ public class Http1ServerAndRequesterTest {
         }
     }
 
+    @Test
+    public void testNonPersistentHeads() throws Exception {
+        server.start();
+        final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(0));
+        final ListenerEndpoint listener = future.get();
+        final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
+        requester.start();
+
+        final HttpHost target = new HttpHost(scheme.id, "localhost", address.getPort());
+        final Queue<Future<Message<HttpResponse, String>>> queue = new LinkedList<>();
+
+        for (int i = 0; i < 20; i++) {
+            final HttpRequest head = new BasicHttpRequest(Methods.HEAD, target, "/no-keep-alive/stuff?p=" + i);
+            queue.add(requester.execute(
+                    new BasicRequestProducer(head, null),
+                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), TIMEOUT, null));
+        }
+
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, String>> resultFuture = queue.remove();
+            final Message<HttpResponse, String> message = resultFuture.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+            Assert.assertThat(message, CoreMatchers.notNullValue());
+            final HttpResponse response = message.getHead();
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(HttpStatus.SC_OK));
+            Assert.assertThat(message.getBody(), CoreMatchers.nullValue());
+        }
+    }
+
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index 2edb807..aebd5aa 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -247,11 +247,12 @@ class ClientHttp1StreamHandler implements ResourceHolder {
         context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
         httpProcessor.process(response, entityDetails, context);
 
+        if (entityDetails == null && !keepAlive) {
+            outputChannel.close();
+        }
+
         exchangeHandler.consumeResponse(response, entityDetails, context);
         if (entityDetails == null) {
-            if (!keepAlive) {
-                outputChannel.close();
-            }
             responseState = MessageState.COMPLETE;
         } else {
             responseState = MessageState.BODY;


[httpcomponents-core] 01/02: Changed wiring of the I/O session logging decorator; I/O session logging classes marked as internal

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch bug-fixes
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git

commit 1186d18980e2b7a9382c1b69240e551e11d9d0fd
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Mon Sep 30 12:22:18 2019 +0200

    Changed wiring of the I/O session logging decorator; I/O session logging classes marked as internal
---
 .../http2/impl/nio/bootstrap/H2AsyncRequester.java |  3 +-
 .../nio/bootstrap/H2MultiplexingRequester.java     |  3 +-
 .../H2MultiplexingRequesterBootstrap.java          |  7 ++--
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  7 ++--
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  8 ++---
 .../apache/hc/core5/benchmark/HttpBenchmark.java   | 33 +++--------------
 .../hc/core5/testing/nio/LoggingIOSession.java     | 41 ++++------------------
 .../testing/nio/LoggingIOSessionDecorator.java     |  8 +++--
 .../testing/nio/LoggingIOSessionListener.java      |  7 ++++
 .../core5/http/impl/bootstrap/AsyncRequester.java  |  3 +-
 .../impl/bootstrap/AsyncRequesterBootstrap.java    |  7 ++--
 .../hc/core5/http/impl/bootstrap/AsyncServer.java  |  3 +-
 .../http/impl/bootstrap/AsyncServerBootstrap.java  |  8 ++---
 .../http/impl/bootstrap/HttpAsyncRequester.java    |  3 +-
 .../core5/http/impl/bootstrap/HttpAsyncServer.java |  4 +--
 .../core5/reactor/DefaultConnectingIOReactor.java  |  2 +-
 .../core5/reactor/DefaultListeningIOReactor.java   |  2 +-
 .../apache/hc/core5/reactor/IOSessionListener.java |  5 +++
 .../hc/core5/reactor/InternalDataChannel.java      |  4 ++-
 .../hc/core5/reactor/SingleCoreIOReactor.java      | 22 +++++++-----
 20 files changed, 72 insertions(+), 108 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
index bd51bc5..de22471 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
@@ -42,7 +42,6 @@ import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -63,7 +62,7 @@ public class H2AsyncRequester extends HttpAsyncRequester {
             final HttpVersionPolicy versionPolicy,
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final ManagedConnPool<HttpHost, IOSession> connPool) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
index c77354f..0d86cc7 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
@@ -73,7 +73,6 @@ import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
@@ -94,7 +93,7 @@ public class H2MultiplexingRequester extends AsyncRequester{
     public H2MultiplexingRequester(
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final Resolver<HttpHost, InetSocketAddress> addressResolver,
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
index 244ab2f..e59802a 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
@@ -49,6 +49,7 @@ import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
@@ -68,7 +69,7 @@ public class H2MultiplexingRequesterBootstrap {
     private H2Config h2Config;
     private TlsStrategy tlsStrategy;
     private boolean strictALPNHandshake;
-    private Decorator<ProtocolIOSession> ioSessionDecorator;
+    private Decorator<IOSession> ioSessionDecorator;
     private Callback<Exception> exceptionCallback;
     private IOSessionListener sessionListener;
     private H2StreamListener streamListener;
@@ -127,9 +128,9 @@ public class H2MultiplexingRequesterBootstrap {
     }
 
     /**
-     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
+     * Assigns {@link IOSession} {@link Decorator} instance.
      */
-    public final H2MultiplexingRequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
+    public final H2MultiplexingRequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
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 5a703b0..c45e677 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,7 +63,6 @@ import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
@@ -90,7 +89,7 @@ public class H2RequesterBootstrap {
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<ProtocolIOSession> ioSessionDecorator;
+    private Decorator<IOSession> ioSessionDecorator;
     private Callback<Exception> exceptionCallback;
     private IOSessionListener sessionListener;
     private H2StreamListener streamListener;
@@ -207,9 +206,9 @@ public class H2RequesterBootstrap {
     }
 
     /**
-     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
+     * Assigns {@link IOSession} {@link Decorator} instance.
      */
-    public final H2RequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
+    public final H2RequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
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 8e1a82a..c37b71b 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
@@ -70,8 +70,8 @@ import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
 import org.apache.hc.core5.net.InetAddressUtils;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Timeout;
 
@@ -94,7 +94,7 @@ public class H2ServerBootstrap {
     private Http1Config http1Config;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<ProtocolIOSession> ioSessionDecorator;
+    private Decorator<IOSession> ioSessionDecorator;
     private Callback<Exception> exceptionCallback;
     private IOSessionListener sessionListener;
     private H2StreamListener h2StreamListener;
@@ -189,9 +189,9 @@ public class H2ServerBootstrap {
     }
 
     /**
-     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
+     * Assigns {@link IOSession} {@link Decorator} instance.
      */
-    public final H2ServerBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
+    public final H2ServerBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
index 3e572ef..9d2c558 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
@@ -69,15 +69,10 @@ import org.apache.hc.core5.http2.protocol.H2RequestConnControl;
 import org.apache.hc.core5.http2.protocol.H2RequestContent;
 import org.apache.hc.core5.http2.protocol.H2RequestTargetHost;
 import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.IOEventHandler;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.ProtocolIOSession;
-import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
-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.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.ssl.SSLContextBuilder;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.ssl.TrustStrategy;
@@ -178,11 +173,11 @@ public class HttpBenchmark {
                 .setHttpProcessor(builder.build())
                 .setTlsStrategy(new BasicClientTlsStrategy(sslContext))
                 .setVersionPolicy(versionPolicy)
-                .setIOSessionDecorator(new Decorator<ProtocolIOSession>() {
+                .setIOSessionDecorator(new Decorator<IOSession>() {
 
                     @Override
-                    public ProtocolIOSession decorate(final ProtocolIOSession ioSession) {
-                        return new ProtocolIOSession() {
+                    public IOSession decorate(final IOSession ioSession) {
+                        return new IOSession() {
 
                             @Override
                             public String getId() {
@@ -323,11 +318,6 @@ public class HttpBenchmark {
                             }
 
                             @Override
-                            public NamedEndpoint getInitialEndpoint() {
-                                return ioSession.getInitialEndpoint();
-                            }
-
-                            @Override
                             public IOEventHandler getHandler() {
                                 return ioSession.getHandler();
                             }
@@ -337,21 +327,6 @@ public class HttpBenchmark {
                                 ioSession.upgrade(handler);
                             }
 
-                            @Override
-                            public void startTls(final SSLContext sslContext,
-                                                 final NamedEndpoint endpoint,
-                                                 final SSLBufferMode sslBufferMode,
-                                                 final SSLSessionInitializer initializer,
-                                                 final SSLSessionVerifier verifier,
-                                                 final Timeout handshakeTimeout) throws UnsupportedOperationException {
-                                ioSession.startTls(
-                                        sslContext, endpoint, sslBufferMode, initializer, verifier, handshakeTimeout);
-                            }
-
-                            @Override
-                            public TlsDetails getTlsDetails() {
-                                return ioSession.getTlsDetails();
-                            }
                         };
                     }
 
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
index 79fae8a..f8e6b83 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSession.java
@@ -34,28 +34,24 @@ import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
 import java.util.concurrent.locks.Lock;
 
-import javax.net.ssl.SSLContext;
-
+import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.IOEventHandler;
+import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
-import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
-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.hc.core5.testing.classic.Wire;
 import org.apache.hc.core5.util.Timeout;
 import org.slf4j.Logger;
 
-public class LoggingIOSession implements ProtocolIOSession {
+@Internal
+public class LoggingIOSession implements IOSession {
 
     private final Logger log;
     private final Wire wireLog;
-    private final ProtocolIOSession session;
+    private final IOSession session;
 
-    public LoggingIOSession(final ProtocolIOSession session, final Logger log, final Logger wireLog) {
+    public LoggingIOSession(final IOSession session, final Logger log, final Logger wireLog) {
         super();
         this.session = session;
         this.log = log;
@@ -80,7 +76,7 @@ public class LoggingIOSession implements ProtocolIOSession {
     public void enqueue(final Command command, final Command.Priority priority) {
         this.session.enqueue(command, priority);
         if (this.log.isDebugEnabled()) {
-            this.log.debug("Enqueued " + command.getClass().getSimpleName() + " with priority " + priority);
+            this.log.debug(this.session + " Enqueued " + command.getClass().getSimpleName() + " with priority " + priority);
         }
     }
 
@@ -259,11 +255,6 @@ public class LoggingIOSession implements ProtocolIOSession {
     }
 
     @Override
-    public NamedEndpoint getInitialEndpoint() {
-        return this.session.getInitialEndpoint();
-    }
-
-    @Override
     public IOEventHandler getHandler() {
         return this.session.getHandler();
     }
@@ -277,24 +268,6 @@ public class LoggingIOSession implements ProtocolIOSession {
     }
 
     @Override
-    public void startTls(final SSLContext sslContext,
-                         final NamedEndpoint endpoint,
-                         final SSLBufferMode sslBufferMode,
-                         final SSLSessionInitializer initializer,
-                         final SSLSessionVerifier verifier,
-                         final Timeout handshakeTimeout) throws UnsupportedOperationException {
-        if (this.log.isDebugEnabled()) {
-            this.log.debug(this.session + " Start TLS");
-        }
-        this.session.startTls(sslContext, endpoint, sslBufferMode, initializer, verifier, handshakeTimeout);
-    }
-
-    @Override
-    public TlsDetails getTlsDetails() {
-        return this.session.getTlsDetails();
-    }
-
-    @Override
     public String toString() {
         return this.session.toString();
     }
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionDecorator.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionDecorator.java
index 4cf5994..b4436f1 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionDecorator.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionDecorator.java
@@ -27,12 +27,14 @@
 
 package org.apache.hc.core5.testing.nio;
 
+import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.reactor.IOSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class LoggingIOSessionDecorator implements Decorator<ProtocolIOSession> {
+@Internal
+public class LoggingIOSessionDecorator implements Decorator<IOSession> {
 
     public final static LoggingIOSessionDecorator INSTANCE = new LoggingIOSessionDecorator();
 
@@ -42,7 +44,7 @@ public class LoggingIOSessionDecorator implements Decorator<ProtocolIOSession> {
     }
 
     @Override
-    public ProtocolIOSession decorate(final ProtocolIOSession ioSession) {
+    public IOSession decorate(final IOSession ioSession) {
         final Logger sessionLog = LoggerFactory.getLogger(ioSession.getClass());
         return new LoggingIOSession(ioSession, sessionLog, wireLog);
     }
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionListener.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionListener.java
index 33597b1..bbd5290 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionListener.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/LoggingIOSessionListener.java
@@ -50,6 +50,13 @@ public class LoggingIOSessionListener implements IOSessionListener {
     }
 
     @Override
+    public void startTls(final IOSession session) {
+        if (connLog.isDebugEnabled()) {
+            connLog.debug(session + " TLS started");
+        }
+    }
+
+    @Override
     public void inputReady(final IOSession session) {
         if (connLog.isDebugEnabled()) {
             connLog.debug(session + " input ready");
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequester.java
index b52ae46..7bfa0a4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequester.java
@@ -48,7 +48,6 @@ import org.apache.hc.core5.reactor.IOReactorService;
 import org.apache.hc.core5.reactor.IOReactorStatus;
 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.TimeValue;
 import org.apache.hc.core5.util.Timeout;
@@ -67,7 +66,7 @@ public class AsyncRequester extends AbstractConnectionInitiatorBase implements I
     public AsyncRequester(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback,
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 4da60ae..5d031ba 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
@@ -51,7 +51,6 @@ import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -73,7 +72,7 @@ public class AsyncRequesterBootstrap {
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<ProtocolIOSession> ioSessionDecorator;
+    private Decorator<IOSession> ioSessionDecorator;
     private Callback<Exception> exceptionCallback;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
@@ -180,9 +179,9 @@ public class AsyncRequesterBootstrap {
     }
 
     /**
-     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
+     * Assigns {@link IOSession} {@link Decorator} instance.
      */
-    public final AsyncRequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
+    public final AsyncRequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServer.java
index 0c4db17..480b592 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServer.java
@@ -48,7 +48,6 @@ import org.apache.hc.core5.reactor.IOReactorStatus;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
-import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
@@ -62,7 +61,7 @@ public class AsyncServer extends AbstractConnectionInitiatorBase implements IORe
     public AsyncServer(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
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 f9189a9..d660b00 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
@@ -63,8 +63,8 @@ import org.apache.hc.core5.http.protocol.UriPatternType;
 import org.apache.hc.core5.net.InetAddressUtils;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Timeout;
 
@@ -86,7 +86,7 @@ public class AsyncServerBootstrap {
     private ConnectionReuseStrategy connStrategy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<ProtocolIOSession> ioSessionDecorator;
+    private Decorator<IOSession> ioSessionDecorator;
     private Callback<Exception> exceptionCallback;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
@@ -173,9 +173,9 @@ public class AsyncServerBootstrap {
     }
 
     /**
-     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
+     * Assigns {@link IOSession} {@link Decorator} instance.
      */
-    public final AsyncServerBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
+    public final AsyncServerBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
index 279ec0f..c6eb91a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
@@ -74,7 +74,6 @@ import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
@@ -95,7 +94,7 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
     public HttpAsyncRequester(
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final ManagedConnPool<HttpHost, IOSession> connPool) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncServer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncServer.java
index d288716..72e5bd6 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncServer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncServer.java
@@ -32,8 +32,8 @@ import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 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.reactor.ProtocolIOSession;
 
 /**
  * HTTP/1.1 server side message exchange handler.
@@ -49,7 +49,7 @@ public class HttpAsyncServer extends AsyncServer {
     public HttpAsyncServer(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener) {
         super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator, exceptionCallback, sessionListener,
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultConnectingIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultConnectingIOReactor.java
index ac10193..1d99e52 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultConnectingIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultConnectingIOReactor.java
@@ -59,7 +59,7 @@ public class DefaultConnectingIOReactor extends AbstractIOReactorBase {
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
             final ThreadFactory threadFactory,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
index edf1fa6..0a9a84c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
@@ -77,7 +77,7 @@ public class DefaultListeningIOReactor extends AbstractIOReactorBase implements
             final IOReactorConfig ioReactorConfig,
             final ThreadFactory dispatchThreadFactory,
             final ThreadFactory listenerThreadFactory,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionListener.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionListener.java
index badf4fa..64f1a40 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionListener.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionListener.java
@@ -27,15 +27,20 @@
 
 package org.apache.hc.core5.reactor;
 
+import org.apache.hc.core5.annotation.Internal;
+
 /**
  * {@link IOSession} even listener.
  *
  * @since 5.0
  */
+@Internal
 public interface IOSessionListener {
 
     void connected(IOSession session);
 
+    void startTls(IOSession session);
+
     void inputReady(IOSession session);
 
     void outputReady(IOSession session);
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 7fce8aa..bc640ce 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
@@ -183,7 +183,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
             final SSLSessionInitializer initializer,
             final SSLSessionVerifier verifier,
             final Timeout handshakeTimeout) {
-        if (!tlsSessionRef.compareAndSet(null, new SSLIOSession(
+        if (tlsSessionRef.compareAndSet(null, new SSLIOSession(
                 endpoint != null ? endpoint : initialEndpoint,
                 ioSession,
                 initialEndpoint != null ? SSLMode.CLIENT : SSLMode.SERVER,
@@ -223,6 +223,8 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
 
                 },
                 handshakeTimeout))) {
+            sessionListener.startTls(this);
+        } else {
             throw new IllegalStateException("TLS already activated");
         }
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
index 7d10b29..78bc3a7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
@@ -61,7 +61,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
 
     private final IOEventHandlerFactory eventHandlerFactory;
     private final IOReactorConfig reactorConfig;
-    private final Decorator<ProtocolIOSession> ioSessionDecorator;
+    private final Decorator<IOSession> ioSessionDecorator;
     private final IOSessionListener sessionListener;
     private final Callback<IOSession> sessionShutdownCallback;
     private final Queue<InternalDataChannel> closedSessions;
@@ -75,7 +75,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
             final Callback<Exception> exceptionCallback,
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig reactorConfig,
-            final Decorator<ProtocolIOSession> ioSessionDecorator,
+            final Decorator<IOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
         super(exceptionCallback);
@@ -207,9 +207,12 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
                 return;
             }
             final IOSession ioSession = new IOSessionImpl(key, socketChannel);
-            final InternalDataChannel dataChannel = new InternalDataChannel(ioSession, null, sessionListener, closedSessions);
-            final ProtocolIOSession protocolSession = ioSessionDecorator != null ? ioSessionDecorator.decorate(dataChannel) : dataChannel;
-            dataChannel.upgrade(this.eventHandlerFactory.createHandler(protocolSession, null));
+            final InternalDataChannel dataChannel = new InternalDataChannel(
+                    ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession,
+                    null,
+                    sessionListener,
+                    closedSessions);
+            dataChannel.upgrade(this.eventHandlerFactory.createHandler(dataChannel, null));
             dataChannel.setSocketTimeout(this.reactorConfig.getSoTimeout());
             key.attach(dataChannel);
             dataChannel.handleIOEvent(SelectionKey.OP_CONNECT);
@@ -361,9 +364,12 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
                     final NamedEndpoint namedEndpoint,
                     final Object attachment) {
                 final IOSession ioSession = new IOSessionImpl(key, socketChannel);
-                final InternalDataChannel dataChannel = new InternalDataChannel(ioSession, namedEndpoint, sessionListener, closedSessions);
-                final ProtocolIOSession protocolSession = ioSessionDecorator != null ? ioSessionDecorator.decorate(dataChannel) : dataChannel;
-                dataChannel.upgrade(eventHandlerFactory.createHandler(protocolSession, attachment));
+                final InternalDataChannel dataChannel = new InternalDataChannel(
+                        ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession,
+                        namedEndpoint,
+                        sessionListener,
+                        closedSessions);
+                dataChannel.upgrade(eventHandlerFactory.createHandler(dataChannel, attachment));
                 dataChannel.setSocketTimeout(reactorConfig.getSoTimeout());
                 return dataChannel;
             }