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/06/07 16:36:29 UTC

[httpcomponents-core] branch master updated (7dfe330 -> d8cf074)

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

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


    from 7dfe330  Updated release notes for HttpCore 5.0-beta8 release
     new 5c28eb2  Improved exception handling in the async HTTP protocol negotiators
     new d8cf074  Improved protocol I/O logging

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.


Summary of changes:
 .../impl/nio/ClientHttpProtocolNegotiator.java     | 71 ++++++++--------------
 .../impl/nio/ServerHttpProtocolNegotiator.java     | 32 +++++++---
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  7 ++-
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  8 +--
 .../impl/nio/bootstrap/Http2AsyncRequester.java    |  3 +-
 .../nio/bootstrap/Http2MultiplexingRequester.java  |  3 +-
 .../Http2MultiplexingRequesterBootstrap.java       |  7 +--
 .../apache/hc/core5/benchmark/HttpBenchmark.java   | 44 ++++++++++++--
 .../hc/core5/testing/nio/LoggingIOSession.java     | 54 ++++++++++++++--
 .../testing/nio/LoggingIOSessionDecorator.java     |  8 +--
 .../testing/nio/LoggingIOSessionListener.java      | 32 +++-------
 .../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 +-
 .../hc/core5/reactor/InternalDataChannel.java      | 10 +--
 .../hc/core5/reactor/SingleCoreIOReactor.java      | 27 +++-----
 21 files changed, 193 insertions(+), 145 deletions(-)


Mix of prefix for type names WAS: [httpcomponents-core] 02/02: Improved protocol I/O logging

Posted by Gary Gregory <ga...@gmail.com>.
Hi All:

Looking at this commit reminds me that:

- Sometimes we have names that start with H2 like H2RequesterBootstrap
- Sometimes we have names that start with Http2 like Http2StreamListener

I find the mix not a good thing and confusing. Same for "H1", see other
email thread.

Gary

On Fri, Jun 7, 2019 at 12:36 PM <ol...@apache.org> wrote:

> This is an automated email from the ASF dual-hosted git repository.
>
> olegk pushed a commit to branch master
> in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
>
> commit d8cf0742d9c4bdb5bc5297add9036b4023b43833
> Author: Oleg Kalnichevski <ol...@apache.org>
> AuthorDate: Fri Jun 7 14:15:36 2019 +0200
>
>     Improved protocol I/O logging
> ---
>  .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  7 +--
>  .../impl/nio/bootstrap/H2ServerBootstrap.java      |  8 ++--
>  .../impl/nio/bootstrap/Http2AsyncRequester.java    |  3 +-
>  .../nio/bootstrap/Http2MultiplexingRequester.java  |  3 +-
>  .../Http2MultiplexingRequesterBootstrap.java       |  7 ++-
>  .../apache/hc/core5/benchmark/HttpBenchmark.java   | 44 ++++++++++++++++--
>  .../hc/core5/testing/nio/LoggingIOSession.java     | 54
> ++++++++++++++++++++--
>  .../testing/nio/LoggingIOSessionDecorator.java     |  8 ++--
>  .../testing/nio/LoggingIOSessionListener.java      | 32 ++++---------
>  .../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 +-
>  .../hc/core5/reactor/InternalDataChannel.java      | 10 +---
>  .../hc/core5/reactor/SingleCoreIOReactor.java      | 27 ++++-------
>  19 files changed, 146 insertions(+), 89 deletions(-)
>
> 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 256c8a9..79d5d49 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
> @@ -61,6 +61,7 @@ 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;
> @@ -87,7 +88,7 @@ public class H2RequesterBootstrap {
>      private PoolConcurrencyPolicy poolConcurrencyPolicy;
>      private TlsStrategy tlsStrategy;
>      private Timeout handshakeTimeout;
> -    private Decorator<IOSession> ioSessionDecorator;
> +    private Decorator<ProtocolIOSession> ioSessionDecorator;
>      private IOSessionListener sessionListener;
>      private Http2StreamListener streamListener;
>      private Http1StreamListener http1StreamListener;
> @@ -195,9 +196,9 @@ public class H2RequesterBootstrap {
>      }
>
>      /**
> -     * Assigns {@link IOSession} {@link Decorator} instance.
> +     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
>       */
> -    public final H2RequesterBootstrap setIOSessionDecorator(final
> Decorator<IOSession> ioSessionDecorator) {
> +    public final H2RequesterBootstrap setIOSessionDecorator(final
> Decorator<ProtocolIOSession> 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 1a51590..649b775 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
> @@ -69,8 +69,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;
>
> @@ -93,7 +93,7 @@ public class H2ServerBootstrap {
>      private H1Config h1Config;
>      private TlsStrategy tlsStrategy;
>      private Timeout handshakeTimeout;
> -    private Decorator<IOSession> ioSessionDecorator;
> +    private Decorator<ProtocolIOSession> ioSessionDecorator;
>      private IOSessionListener sessionListener;
>      private Http2StreamListener http2StreamListener;
>      private Http1StreamListener http1StreamListener;
> @@ -179,9 +179,9 @@ public class H2ServerBootstrap {
>      }
>
>      /**
> -     * Assigns {@link IOSession} {@link Decorator} instance.
> +     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
>       */
> -    public final H2ServerBootstrap setIOSessionDecorator(final
> Decorator<IOSession> ioSessionDecorator) {
> +    public final H2ServerBootstrap setIOSessionDecorator(final
> Decorator<ProtocolIOSession> ioSessionDecorator) {
>          this.ioSessionDecorator = ioSessionDecorator;
>          return this;
>      }
> diff --git
> a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
> b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
> index 06c167a..128c100 100644
> ---
> a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
> +++
> b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
> @@ -41,6 +41,7 @@ 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;
>
>  /**
> @@ -61,7 +62,7 @@ public class Http2AsyncRequester extends
> HttpAsyncRequester {
>              final HttpVersionPolicy versionPolicy,
>              final IOReactorConfig ioReactorConfig,
>              final IOEventHandlerFactory eventHandlerFactory,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final ManagedConnPool<HttpHost, IOSession> connPool) {
>          super(ioReactorConfig, eventHandlerFactory, ioSessionDecorator,
> sessionListener, connPool);
> 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..63bfbbf 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
> @@ -71,6 +71,7 @@ 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;
> @@ -91,7 +92,7 @@ public class Http2MultiplexingRequester extends
> AsyncRequester{
>      public Http2MultiplexingRequester(
>              final IOReactorConfig ioReactorConfig,
>              final IOEventHandlerFactory eventHandlerFactory,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Resolver<HttpHost, InetSocketAddress> addressResolver,
>              final TlsStrategy tlsStrategy) {
> 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 2ec7801..afd7fc7 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
> @@ -48,7 +48,6 @@ 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 +67,7 @@ public class Http2MultiplexingRequesterBootstrap {
>      private H2Config h2Config;
>      private TlsStrategy tlsStrategy;
>      private boolean strictALPNHandshake;
> -    private Decorator<IOSession> ioSessionDecorator;
> +    private Decorator<ProtocolIOSession> ioSessionDecorator;
>      private IOSessionListener sessionListener;
>      private Http2StreamListener streamListener;
>
> @@ -126,9 +125,9 @@ public class Http2MultiplexingRequesterBootstrap {
>      }
>
>      /**
> -     * Assigns {@link IOSession} {@link Decorator} instance.
> +     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
>       */
> -    public final Http2MultiplexingRequesterBootstrap
> setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
> +    public final Http2MultiplexingRequesterBootstrap
> setIOSessionDecorator(final Decorator<ProtocolIOSession>
> 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 e3a6c02..d8c1910 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,9 +69,15 @@ 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.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.ssl.SSLContextBuilder;
>  import org.apache.hc.core5.ssl.SSLContexts;
>  import org.apache.hc.core5.ssl.TrustStrategy;
> @@ -172,11 +178,11 @@ public class HttpBenchmark {
>                  .setHttpProcessor(builder.build())
>                  .setTlsStrategy(new BasicClientTlsStrategy(sslContext))
>                  .setVersionPolicy(versionPolicy)
> -                .setIOSessionDecorator(new Decorator<IOSession>() {
> +                .setIOSessionDecorator(new Decorator<ProtocolIOSession>()
> {
>
>                      @Override
> -                    public IOSession decorate(final IOSession ioSession) {
> -                        return new IOSession() {
> +                    public ProtocolIOSession decorate(final
> ProtocolIOSession ioSession) {
> +                        return new ProtocolIOSession() {
>
>                              @Override
>                              public String getId() {
> @@ -317,6 +323,36 @@ public class HttpBenchmark {
>                                  ioSession.close(closeMode);
>                              }
>
> +                            @Override
> +                            public NamedEndpoint getInitialEndpoint() {
> +                                return ioSession.getInitialEndpoint();
> +                            }
> +
> +                            @Override
> +                            public IOEventHandler getHandler() {
> +                                return ioSession.getHandler();
> +                            }
> +
> +                            @Override
> +                            public void upgrade(final IOEventHandler
> handler) {
> +                                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 b29beb2..65acd74 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,21 +34,29 @@ 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.io.CloseMode;
> +import org.apache.hc.core5.net.NamedEndpoint;
>  import org.apache.hc.core5.reactor.Command;
> -import org.apache.hc.core5.reactor.IOSession;
> +import org.apache.hc.core5.reactor.IOEventHandler;
> +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 IOSession {
> +public class LoggingIOSession implements ProtocolIOSession {
>
>      private final Logger log;
>      private final Wire wireLog;
> -    private final IOSession session;
> +    private final ProtocolIOSession session;
>      private final ByteChannel channel;
>
> -    public LoggingIOSession(final IOSession session, final Logger log,
> final Logger wireLog) {
> +    public LoggingIOSession(final ProtocolIOSession session, final Logger
> log, final Logger wireLog) {
>          super();
>          this.session = session;
>          this.log = log;
> @@ -56,7 +64,7 @@ public class LoggingIOSession implements IOSession {
>          this.channel = wireLog != null ? new LoggingByteChannel() :
> session.channel();
>      }
>
> -    public LoggingIOSession(final IOSession session, final Logger log) {
> +    public LoggingIOSession(final ProtocolIOSession session, final Logger
> log) {
>          this(session, log, null);
>      }
>
> @@ -211,6 +219,42 @@ public class LoggingIOSession implements IOSession {
>      }
>
>      @Override
> +    public NamedEndpoint getInitialEndpoint() {
> +        return this.session.getInitialEndpoint();
> +    }
> +
> +    @Override
> +    public IOEventHandler getHandler() {
> +        return this.session.getHandler();
> +    }
> +
> +    @Override
> +    public void upgrade(final IOEventHandler handler) {
> +        if (this.log.isDebugEnabled()) {
> +            this.log.debug(this.session + " Protocol upgrade: " +
> (handler != null ? handler.getClass() : null));
> +        }
> +        this.session.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 {
> +        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 ac33f40..4cf5994 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
> @@ -28,11 +28,11 @@
>  package org.apache.hc.core5.testing.nio;
>
>  import org.apache.hc.core5.function.Decorator;
> -import org.apache.hc.core5.reactor.IOSession;
> -import org.slf4j.LoggerFactory;
> +import org.apache.hc.core5.reactor.ProtocolIOSession;
>  import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
>
> -public class LoggingIOSessionDecorator implements Decorator<IOSession> {
> +public class LoggingIOSessionDecorator implements
> Decorator<ProtocolIOSession> {
>
>      public final static LoggingIOSessionDecorator INSTANCE = new
> LoggingIOSessionDecorator();
>
> @@ -42,7 +42,7 @@ public class LoggingIOSessionDecorator implements
> Decorator<IOSession> {
>      }
>
>      @Override
> -    public IOSession decorate(final IOSession ioSession) {
> +    public ProtocolIOSession decorate(final ProtocolIOSession 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 6a785ca..09aae51 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
> @@ -28,10 +28,8 @@
>  package org.apache.hc.core5.testing.nio;
>
>  import org.apache.hc.core5.http.ConnectionClosedException;
> -import org.apache.hc.core5.net.InetAddressUtils;
>  import org.apache.hc.core5.reactor.IOSession;
>  import org.apache.hc.core5.reactor.IOSessionListener;
> -import org.apache.hc.core5.testing.classic.LoggingSupport;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
>
> @@ -47,49 +45,49 @@ public class LoggingIOSessionListener implements
> IOSessionListener {
>      @Override
>      public void tlsStarted(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " TLS session
> started: " + formatSession(session));
> +            connLog.debug(session + " TLS session started");
>          }
>      }
>
>      @Override
>      public void tlsInbound(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " TLS inbound:
> " + formatSession(session));
> +            connLog.debug(session + " TLS inbound");
>          }
>      }
>
>      @Override
>      public void tlsOutbound(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " TLS outbound:
> " + formatSession(session));
> +            connLog.debug(session + " TLS outbound");
>          }
>      }
>
>      @Override
>      public void connected(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " connected: "
> + formatSession(session));
> +            connLog.debug(session + " connected");
>          }
>      }
>
>      @Override
>      public void inputReady(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " input ready:
> " + formatSession(session));
> +            connLog.debug(session + " input ready");
>          }
>      }
>
>      @Override
>      public void outputReady(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " output ready:
> " + formatSession(session));
> +            connLog.debug(session + " output ready");
>          }
>      }
>
>      @Override
>      public void timeout(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + " timeout: " +
> formatSession(session));
> +            connLog.debug(session + " timeout");
>          }
>      }
>
> @@ -98,26 +96,14 @@ public class LoggingIOSessionListener implements
> IOSessionListener {
>          if (ex instanceof ConnectionClosedException) {
>              return;
>          }
> -        connLog.error(LoggingSupport.getId(session) + " " +
> ex.getMessage(), ex);
> +        connLog.error(session + " " + ex.getMessage(), ex);
>      }
>
>      @Override
>      public void disconnected(final IOSession session) {
>          if (connLog.isDebugEnabled()) {
> -            connLog.debug(LoggingSupport.getId(session) + "
> disconnected");
> +            connLog.debug(session + " disconnected");
>          }
>      }
>
> -    private static String formatSession(final IOSession session) {
> -        final StringBuilder buffer = new StringBuilder(90);
> -        if (session.isClosed()) {
> -            buffer.append("closed");
> -        } else {
> -            InetAddressUtils.formatAddress(buffer,
> session.getLocalAddress());
> -            buffer.append("<->");
> -            InetAddressUtils.formatAddress(buffer,
> session.getRemoteAddress());
> -        }
> -        return buffer.toString();
> -    }
> -
>  }
> 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 f9a9beb..29a2983 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
> @@ -50,6 +50,7 @@ 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;
> @@ -68,7 +69,7 @@ public class AsyncRequester extends
> AbstractConnectionInitiatorBase implements I
>      public AsyncRequester(
>              final IOEventHandlerFactory eventHandlerFactory,
>              final IOReactorConfig ioReactorConfig,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Callback<IOSession> sessionShutdownCallback,
>              final Resolver<HttpHost, InetSocketAddress> addressResolver) {
> 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 1432394..06b9e49 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
> @@ -49,6 +49,7 @@ 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;
>
>  /**
> @@ -70,7 +71,7 @@ public class AsyncRequesterBootstrap {
>      private PoolConcurrencyPolicy poolConcurrencyPolicy;
>      private TlsStrategy tlsStrategy;
>      private Timeout handshakeTimeout;
> -    private Decorator<IOSession> ioSessionDecorator;
> +    private Decorator<ProtocolIOSession> ioSessionDecorator;
>      private IOSessionListener sessionListener;
>      private Http1StreamListener streamListener;
>      private ConnPoolListener<HttpHost> connPoolListener;
> @@ -168,9 +169,9 @@ public class AsyncRequesterBootstrap {
>      }
>
>      /**
> -     * Assigns {@link IOSession} {@link Decorator} instance.
> +     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
>       */
> -    public final AsyncRequesterBootstrap setIOSessionDecorator(final
> Decorator<IOSession> ioSessionDecorator) {
> +    public final AsyncRequesterBootstrap setIOSessionDecorator(final
> Decorator<ProtocolIOSession> 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 04a4630..4eb09c5 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
> @@ -50,6 +50,7 @@ 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;
>
>  /**
> @@ -63,7 +64,7 @@ public class AsyncServer extends
> AbstractConnectionInitiatorBase implements IORe
>      public AsyncServer(
>              final IOEventHandlerFactory eventHandlerFactory,
>              final IOReactorConfig ioReactorConfig,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Callback<IOSession> sessionShutdownCallback) {
>          this.ioReactor = new DefaultListeningIOReactor(
> 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 2efe675..509ea98 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
> @@ -62,8 +62,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;
>
> @@ -85,7 +85,7 @@ public class AsyncServerBootstrap {
>      private ConnectionReuseStrategy connStrategy;
>      private TlsStrategy tlsStrategy;
>      private Timeout handshakeTimeout;
> -    private Decorator<IOSession> ioSessionDecorator;
> +    private Decorator<ProtocolIOSession> ioSessionDecorator;
>      private IOSessionListener sessionListener;
>      private Http1StreamListener streamListener;
>
> @@ -163,9 +163,9 @@ public class AsyncServerBootstrap {
>      }
>
>      /**
> -     * Assigns {@link IOSession} {@link Decorator} instance.
> +     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
>       */
> -    public final AsyncServerBootstrap setIOSessionDecorator(final
> Decorator<IOSession> ioSessionDecorator) {
> +    public final AsyncServerBootstrap setIOSessionDecorator(final
> Decorator<ProtocolIOSession> 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 13dafe5..0dff2f7 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
> @@ -72,6 +72,7 @@ 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;
> @@ -92,7 +93,7 @@ public class HttpAsyncRequester extends AsyncRequester
> implements ConnPoolContro
>      public HttpAsyncRequester(
>              final IOReactorConfig ioReactorConfig,
>              final IOEventHandlerFactory eventHandlerFactory,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final ManagedConnPool<HttpHost, IOSession> connPool) {
>          super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator,
> sessionListener,
> 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 46c1cbd..e965742 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
> @@ -31,8 +31,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.
> @@ -48,7 +48,7 @@ public class HttpAsyncServer extends AsyncServer {
>      public HttpAsyncServer(
>              final IOEventHandlerFactory eventHandlerFactory,
>              final IOReactorConfig ioReactorConfig,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener) {
>          super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator,
> sessionListener,
>                          ShutdownCommand.GRACEFUL_NORMAL_CALLBACK);
> 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 a421ecb..1b10cde 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
> @@ -65,7 +65,7 @@ public class DefaultConnectingIOReactor extends
> AbstractIOReactorBase {
>              final IOEventHandlerFactory eventHandlerFactory,
>              final IOReactorConfig ioReactorConfig,
>              final ThreadFactory threadFactory,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Callback<IOSession> sessionShutdownCallback) {
>          Args.notNull(eventHandlerFactory, "Event handler factory");
> 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 64500c9..aad2664 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
> @@ -83,7 +83,7 @@ public class DefaultListeningIOReactor extends
> AbstractIOReactorBase implements
>              final IOReactorConfig ioReactorConfig,
>              final ThreadFactory dispatchThreadFactory,
>              final ThreadFactory listenerThreadFactory,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Callback<IOSession> sessionShutdownCallback) {
>          Args.notNull(eventHandlerFactory, "Event handler factory");
> 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 61b3207..c2f78f5 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
> @@ -395,18 +395,12 @@ final class InternalDataChannel extends
> InternalChannel implements ProtocolIOSes
>
>      @Override
>      public String toString() {
> -        final StringBuilder buf = new StringBuilder();
>          final SSLIOSession tlsSession = tlsSessionRef.get();
>          if (tlsSession != null) {
> -            buf.append(tlsSession);
> +            return tlsSession.toString();
>          } else {
> -            buf.append(ioSession);
> +            return ioSession.toString();
>          }
> -        final IOEventHandler handler = getHandler();
> -        if (handler != null) {
> -            buf.append(handler);
> -        }
> -        return buf.toString();
>      }
>
>  }
> 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 412ce30..b36f16a 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
> @@ -45,7 +45,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
>  import org.apache.hc.core5.concurrent.FutureCallback;
>  import org.apache.hc.core5.function.Callback;
>  import org.apache.hc.core5.function.Decorator;
> -import org.apache.hc.core5.io.CloseMode;
>  import org.apache.hc.core5.io.Closer;
>  import org.apache.hc.core5.net.NamedEndpoint;
>  import org.apache.hc.core5.util.Args;
> @@ -57,7 +56,7 @@ class SingleCoreIOReactor extends
> AbstractSingleCoreIOReactor implements Connect
>
>      private final IOEventHandlerFactory eventHandlerFactory;
>      private final IOReactorConfig reactorConfig;
> -    private final Decorator<IOSession> ioSessionDecorator;
> +    private final Decorator<ProtocolIOSession> ioSessionDecorator;
>      private final IOSessionListener sessionListener;
>      private final Callback<IOSession> sessionShutdownCallback;
>      private final Queue<InternalDataChannel> closedSessions;
> @@ -71,7 +70,7 @@ class SingleCoreIOReactor extends
> AbstractSingleCoreIOReactor implements Connect
>              final Queue<ExceptionEvent> auditLog,
>              final IOEventHandlerFactory eventHandlerFactory,
>              final IOReactorConfig reactorConfig,
> -            final Decorator<IOSession> ioSessionDecorator,
> +            final Decorator<ProtocolIOSession> ioSessionDecorator,
>              final IOSessionListener sessionListener,
>              final Callback<IOSession> sessionShutdownCallback) {
>          super(auditLog);
> @@ -170,11 +169,7 @@ class SingleCoreIOReactor extends
> AbstractSingleCoreIOReactor implements Connect
>      private void processEvents(final Set<SelectionKey> selectedKeys) {
>          for (final SelectionKey key : selectedKeys) {
>              final InternalChannel channel = (InternalChannel)
> key.attachment();
> -            try {
> -                channel.handleIOEvent(key.readyOps());
> -            } catch (final CancelledKeyException ex) {
> -                channel.close(CloseMode.GRACEFUL);
> -            }
> +            channel.handleIOEvent(key.readyOps());
>          }
>          selectedKeys.clear();
>      }
> @@ -200,12 +195,10 @@ class SingleCoreIOReactor extends
> AbstractSingleCoreIOReactor implements Connect
>              } catch (final ClosedChannelException ex) {
>                  return;
>              }
> -            IOSession ioSession = new IOSessionImpl(key, socketChannel);
> -            if (ioSessionDecorator != null) {
> -                ioSession = ioSessionDecorator.decorate(ioSession);
> -            }
> +            final IOSession ioSession = new IOSessionImpl(key,
> socketChannel);
>              final InternalDataChannel dataChannel = new
> InternalDataChannel(ioSession, null, sessionListener, closedSessions);
> -
> dataChannel.upgrade(this.eventHandlerFactory.createHandler(dataChannel,
> null));
> +            final ProtocolIOSession protocolSession = ioSessionDecorator
> != null ? ioSessionDecorator.decorate(dataChannel) : dataChannel;
> +
> dataChannel.upgrade(this.eventHandlerFactory.createHandler(protocolSession,
> null));
>
>  dataChannel.setSocketTimeout(this.reactorConfig.getSoTimeout());
>              key.attach(dataChannel);
>              dataChannel.handleIOEvent(SelectionKey.OP_CONNECT);
> @@ -337,12 +330,10 @@ class SingleCoreIOReactor extends
> AbstractSingleCoreIOReactor implements Connect
>                      final SocketChannel socketChannel,
>                      final NamedEndpoint namedEndpoint,
>                      final Object attachment) {
> -                IOSession ioSession = new IOSessionImpl(key,
> socketChannel);
> -                if (ioSessionDecorator != null) {
> -                    ioSession = ioSessionDecorator.decorate(ioSession);
> -                }
> +                final IOSession ioSession = new IOSessionImpl(key,
> socketChannel);
>                  final InternalDataChannel dataChannel = new
> InternalDataChannel(ioSession, namedEndpoint, sessionListener,
> closedSessions);
> -
> dataChannel.upgrade(eventHandlerFactory.createHandler(dataChannel,
> attachment));
> +                final ProtocolIOSession protocolSession =
> ioSessionDecorator != null ? ioSessionDecorator.decorate(dataChannel) :
> dataChannel;
> +
> dataChannel.upgrade(eventHandlerFactory.createHandler(protocolSession,
> attachment));
>
>  dataChannel.setSocketTimeout(reactorConfig.getSoTimeout());
>                  return dataChannel;
>              }
>
>

[httpcomponents-core] 02/02: Improved protocol I/O logging

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

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

commit d8cf0742d9c4bdb5bc5297add9036b4023b43833
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Fri Jun 7 14:15:36 2019 +0200

    Improved protocol I/O logging
---
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  7 +--
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  8 ++--
 .../impl/nio/bootstrap/Http2AsyncRequester.java    |  3 +-
 .../nio/bootstrap/Http2MultiplexingRequester.java  |  3 +-
 .../Http2MultiplexingRequesterBootstrap.java       |  7 ++-
 .../apache/hc/core5/benchmark/HttpBenchmark.java   | 44 ++++++++++++++++--
 .../hc/core5/testing/nio/LoggingIOSession.java     | 54 ++++++++++++++++++++--
 .../testing/nio/LoggingIOSessionDecorator.java     |  8 ++--
 .../testing/nio/LoggingIOSessionListener.java      | 32 ++++---------
 .../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 +-
 .../hc/core5/reactor/InternalDataChannel.java      | 10 +---
 .../hc/core5/reactor/SingleCoreIOReactor.java      | 27 ++++-------
 19 files changed, 146 insertions(+), 89 deletions(-)

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 256c8a9..79d5d49 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
@@ -61,6 +61,7 @@ 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;
@@ -87,7 +88,7 @@ public class H2RequesterBootstrap {
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<IOSession> ioSessionDecorator;
+    private Decorator<ProtocolIOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http2StreamListener streamListener;
     private Http1StreamListener http1StreamListener;
@@ -195,9 +196,9 @@ public class H2RequesterBootstrap {
     }
 
     /**
-     * Assigns {@link IOSession} {@link Decorator} instance.
+     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
      */
-    public final H2RequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
+    public final H2RequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> 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 1a51590..649b775 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
@@ -69,8 +69,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;
 
@@ -93,7 +93,7 @@ public class H2ServerBootstrap {
     private H1Config h1Config;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<IOSession> ioSessionDecorator;
+    private Decorator<ProtocolIOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http2StreamListener http2StreamListener;
     private Http1StreamListener http1StreamListener;
@@ -179,9 +179,9 @@ public class H2ServerBootstrap {
     }
 
     /**
-     * Assigns {@link IOSession} {@link Decorator} instance.
+     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
      */
-    public final H2ServerBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
+    public final H2ServerBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> ioSessionDecorator) {
         this.ioSessionDecorator = ioSessionDecorator;
         return this;
     }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
index 06c167a..128c100 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/Http2AsyncRequester.java
@@ -41,6 +41,7 @@ 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;
 
 /**
@@ -61,7 +62,7 @@ public class Http2AsyncRequester extends HttpAsyncRequester {
             final HttpVersionPolicy versionPolicy,
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final ManagedConnPool<HttpHost, IOSession> connPool) {
         super(ioReactorConfig, eventHandlerFactory, ioSessionDecorator, sessionListener, connPool);
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..63bfbbf 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
@@ -71,6 +71,7 @@ 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;
@@ -91,7 +92,7 @@ public class Http2MultiplexingRequester extends AsyncRequester{
     public Http2MultiplexingRequester(
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Resolver<HttpHost, InetSocketAddress> addressResolver,
             final TlsStrategy tlsStrategy) {
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 2ec7801..afd7fc7 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
@@ -48,7 +48,6 @@ 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 +67,7 @@ public class Http2MultiplexingRequesterBootstrap {
     private H2Config h2Config;
     private TlsStrategy tlsStrategy;
     private boolean strictALPNHandshake;
-    private Decorator<IOSession> ioSessionDecorator;
+    private Decorator<ProtocolIOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http2StreamListener streamListener;
 
@@ -126,9 +125,9 @@ public class Http2MultiplexingRequesterBootstrap {
     }
 
     /**
-     * Assigns {@link IOSession} {@link Decorator} instance.
+     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
      */
-    public final Http2MultiplexingRequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
+    public final Http2MultiplexingRequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> 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 e3a6c02..d8c1910 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,9 +69,15 @@ 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.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.ssl.SSLContextBuilder;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.ssl.TrustStrategy;
@@ -172,11 +178,11 @@ public class HttpBenchmark {
                 .setHttpProcessor(builder.build())
                 .setTlsStrategy(new BasicClientTlsStrategy(sslContext))
                 .setVersionPolicy(versionPolicy)
-                .setIOSessionDecorator(new Decorator<IOSession>() {
+                .setIOSessionDecorator(new Decorator<ProtocolIOSession>() {
 
                     @Override
-                    public IOSession decorate(final IOSession ioSession) {
-                        return new IOSession() {
+                    public ProtocolIOSession decorate(final ProtocolIOSession ioSession) {
+                        return new ProtocolIOSession() {
 
                             @Override
                             public String getId() {
@@ -317,6 +323,36 @@ public class HttpBenchmark {
                                 ioSession.close(closeMode);
                             }
 
+                            @Override
+                            public NamedEndpoint getInitialEndpoint() {
+                                return ioSession.getInitialEndpoint();
+                            }
+
+                            @Override
+                            public IOEventHandler getHandler() {
+                                return ioSession.getHandler();
+                            }
+
+                            @Override
+                            public void upgrade(final IOEventHandler handler) {
+                                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 b29beb2..65acd74 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,21 +34,29 @@ 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.io.CloseMode;
+import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.Command;
-import org.apache.hc.core5.reactor.IOSession;
+import org.apache.hc.core5.reactor.IOEventHandler;
+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 IOSession {
+public class LoggingIOSession implements ProtocolIOSession {
 
     private final Logger log;
     private final Wire wireLog;
-    private final IOSession session;
+    private final ProtocolIOSession session;
     private final ByteChannel channel;
 
-    public LoggingIOSession(final IOSession session, final Logger log, final Logger wireLog) {
+    public LoggingIOSession(final ProtocolIOSession session, final Logger log, final Logger wireLog) {
         super();
         this.session = session;
         this.log = log;
@@ -56,7 +64,7 @@ public class LoggingIOSession implements IOSession {
         this.channel = wireLog != null ? new LoggingByteChannel() : session.channel();
     }
 
-    public LoggingIOSession(final IOSession session, final Logger log) {
+    public LoggingIOSession(final ProtocolIOSession session, final Logger log) {
         this(session, log, null);
     }
 
@@ -211,6 +219,42 @@ public class LoggingIOSession implements IOSession {
     }
 
     @Override
+    public NamedEndpoint getInitialEndpoint() {
+        return this.session.getInitialEndpoint();
+    }
+
+    @Override
+    public IOEventHandler getHandler() {
+        return this.session.getHandler();
+    }
+
+    @Override
+    public void upgrade(final IOEventHandler handler) {
+        if (this.log.isDebugEnabled()) {
+            this.log.debug(this.session + " Protocol upgrade: " + (handler != null ? handler.getClass() : null));
+        }
+        this.session.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 {
+        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 ac33f40..4cf5994 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
@@ -28,11 +28,11 @@
 package org.apache.hc.core5.testing.nio;
 
 import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.reactor.IOSession;
-import org.slf4j.LoggerFactory;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class LoggingIOSessionDecorator implements Decorator<IOSession> {
+public class LoggingIOSessionDecorator implements Decorator<ProtocolIOSession> {
 
     public final static LoggingIOSessionDecorator INSTANCE = new LoggingIOSessionDecorator();
 
@@ -42,7 +42,7 @@ public class LoggingIOSessionDecorator implements Decorator<IOSession> {
     }
 
     @Override
-    public IOSession decorate(final IOSession ioSession) {
+    public ProtocolIOSession decorate(final ProtocolIOSession 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 6a785ca..09aae51 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
@@ -28,10 +28,8 @@
 package org.apache.hc.core5.testing.nio;
 
 import org.apache.hc.core5.http.ConnectionClosedException;
-import org.apache.hc.core5.net.InetAddressUtils;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.IOSessionListener;
-import org.apache.hc.core5.testing.classic.LoggingSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,49 +45,49 @@ public class LoggingIOSessionListener implements IOSessionListener {
     @Override
     public void tlsStarted(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " TLS session started: " + formatSession(session));
+            connLog.debug(session + " TLS session started");
         }
     }
 
     @Override
     public void tlsInbound(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " TLS inbound: " + formatSession(session));
+            connLog.debug(session + " TLS inbound");
         }
     }
 
     @Override
     public void tlsOutbound(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " TLS outbound: " + formatSession(session));
+            connLog.debug(session + " TLS outbound");
         }
     }
 
     @Override
     public void connected(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " connected: " + formatSession(session));
+            connLog.debug(session + " connected");
         }
     }
 
     @Override
     public void inputReady(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " input ready: " + formatSession(session));
+            connLog.debug(session + " input ready");
         }
     }
 
     @Override
     public void outputReady(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " output ready: " + formatSession(session));
+            connLog.debug(session + " output ready");
         }
     }
 
     @Override
     public void timeout(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " timeout: " + formatSession(session));
+            connLog.debug(session + " timeout");
         }
     }
 
@@ -98,26 +96,14 @@ public class LoggingIOSessionListener implements IOSessionListener {
         if (ex instanceof ConnectionClosedException) {
             return;
         }
-        connLog.error(LoggingSupport.getId(session) + " " + ex.getMessage(), ex);
+        connLog.error(session + " " + ex.getMessage(), ex);
     }
 
     @Override
     public void disconnected(final IOSession session) {
         if (connLog.isDebugEnabled()) {
-            connLog.debug(LoggingSupport.getId(session) + " disconnected");
+            connLog.debug(session + " disconnected");
         }
     }
 
-    private static String formatSession(final IOSession session) {
-        final StringBuilder buffer = new StringBuilder(90);
-        if (session.isClosed()) {
-            buffer.append("closed");
-        } else {
-            InetAddressUtils.formatAddress(buffer, session.getLocalAddress());
-            buffer.append("<->");
-            InetAddressUtils.formatAddress(buffer, session.getRemoteAddress());
-        }
-        return buffer.toString();
-    }
-
 }
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 f9a9beb..29a2983 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
@@ -50,6 +50,7 @@ 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;
@@ -68,7 +69,7 @@ public class AsyncRequester extends AbstractConnectionInitiatorBase implements I
     public AsyncRequester(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback,
             final Resolver<HttpHost, InetSocketAddress> addressResolver) {
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 1432394..06b9e49 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
@@ -49,6 +49,7 @@ 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;
 
 /**
@@ -70,7 +71,7 @@ public class AsyncRequesterBootstrap {
     private PoolConcurrencyPolicy poolConcurrencyPolicy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<IOSession> ioSessionDecorator;
+    private Decorator<ProtocolIOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
     private ConnPoolListener<HttpHost> connPoolListener;
@@ -168,9 +169,9 @@ public class AsyncRequesterBootstrap {
     }
 
     /**
-     * Assigns {@link IOSession} {@link Decorator} instance.
+     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
      */
-    public final AsyncRequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
+    public final AsyncRequesterBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> 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 04a4630..4eb09c5 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
@@ -50,6 +50,7 @@ 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;
 
 /**
@@ -63,7 +64,7 @@ public class AsyncServer extends AbstractConnectionInitiatorBase implements IORe
     public AsyncServer(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
         this.ioReactor = new DefaultListeningIOReactor(
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 2efe675..509ea98 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
@@ -62,8 +62,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;
 
@@ -85,7 +85,7 @@ public class AsyncServerBootstrap {
     private ConnectionReuseStrategy connStrategy;
     private TlsStrategy tlsStrategy;
     private Timeout handshakeTimeout;
-    private Decorator<IOSession> ioSessionDecorator;
+    private Decorator<ProtocolIOSession> ioSessionDecorator;
     private IOSessionListener sessionListener;
     private Http1StreamListener streamListener;
 
@@ -163,9 +163,9 @@ public class AsyncServerBootstrap {
     }
 
     /**
-     * Assigns {@link IOSession} {@link Decorator} instance.
+     * Assigns {@link ProtocolIOSession} {@link Decorator} instance.
      */
-    public final AsyncServerBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
+    public final AsyncServerBootstrap setIOSessionDecorator(final Decorator<ProtocolIOSession> 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 13dafe5..0dff2f7 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
@@ -72,6 +72,7 @@ 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;
@@ -92,7 +93,7 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
     public HttpAsyncRequester(
             final IOReactorConfig ioReactorConfig,
             final IOEventHandlerFactory eventHandlerFactory,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final ManagedConnPool<HttpHost, IOSession> connPool) {
         super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener,
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 46c1cbd..e965742 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
@@ -31,8 +31,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.
@@ -48,7 +48,7 @@ public class HttpAsyncServer extends AsyncServer {
     public HttpAsyncServer(
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener) {
         super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener,
                         ShutdownCommand.GRACEFUL_NORMAL_CALLBACK);
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 a421ecb..1b10cde 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
@@ -65,7 +65,7 @@ public class DefaultConnectingIOReactor extends AbstractIOReactorBase {
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig ioReactorConfig,
             final ThreadFactory threadFactory,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
         Args.notNull(eventHandlerFactory, "Event handler factory");
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 64500c9..aad2664 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
@@ -83,7 +83,7 @@ public class DefaultListeningIOReactor extends AbstractIOReactorBase implements
             final IOReactorConfig ioReactorConfig,
             final ThreadFactory dispatchThreadFactory,
             final ThreadFactory listenerThreadFactory,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
         Args.notNull(eventHandlerFactory, "Event handler factory");
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 61b3207..c2f78f5 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
@@ -395,18 +395,12 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
 
     @Override
     public String toString() {
-        final StringBuilder buf = new StringBuilder();
         final SSLIOSession tlsSession = tlsSessionRef.get();
         if (tlsSession != null) {
-            buf.append(tlsSession);
+            return tlsSession.toString();
         } else {
-            buf.append(ioSession);
+            return ioSession.toString();
         }
-        final IOEventHandler handler = getHandler();
-        if (handler != null) {
-            buf.append(handler);
-        }
-        return buf.toString();
     }
 
 }
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 412ce30..b36f16a 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
@@ -45,7 +45,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.io.Closer;
 import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.util.Args;
@@ -57,7 +56,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
 
     private final IOEventHandlerFactory eventHandlerFactory;
     private final IOReactorConfig reactorConfig;
-    private final Decorator<IOSession> ioSessionDecorator;
+    private final Decorator<ProtocolIOSession> ioSessionDecorator;
     private final IOSessionListener sessionListener;
     private final Callback<IOSession> sessionShutdownCallback;
     private final Queue<InternalDataChannel> closedSessions;
@@ -71,7 +70,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
             final Queue<ExceptionEvent> auditLog,
             final IOEventHandlerFactory eventHandlerFactory,
             final IOReactorConfig reactorConfig,
-            final Decorator<IOSession> ioSessionDecorator,
+            final Decorator<ProtocolIOSession> ioSessionDecorator,
             final IOSessionListener sessionListener,
             final Callback<IOSession> sessionShutdownCallback) {
         super(auditLog);
@@ -170,11 +169,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
     private void processEvents(final Set<SelectionKey> selectedKeys) {
         for (final SelectionKey key : selectedKeys) {
             final InternalChannel channel = (InternalChannel) key.attachment();
-            try {
-                channel.handleIOEvent(key.readyOps());
-            } catch (final CancelledKeyException ex) {
-                channel.close(CloseMode.GRACEFUL);
-            }
+            channel.handleIOEvent(key.readyOps());
         }
         selectedKeys.clear();
     }
@@ -200,12 +195,10 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
             } catch (final ClosedChannelException ex) {
                 return;
             }
-            IOSession ioSession = new IOSessionImpl(key, socketChannel);
-            if (ioSessionDecorator != null) {
-                ioSession = ioSessionDecorator.decorate(ioSession);
-            }
+            final IOSession ioSession = new IOSessionImpl(key, socketChannel);
             final InternalDataChannel dataChannel = new InternalDataChannel(ioSession, null, sessionListener, closedSessions);
-            dataChannel.upgrade(this.eventHandlerFactory.createHandler(dataChannel, null));
+            final ProtocolIOSession protocolSession = ioSessionDecorator != null ? ioSessionDecorator.decorate(dataChannel) : dataChannel;
+            dataChannel.upgrade(this.eventHandlerFactory.createHandler(protocolSession, null));
             dataChannel.setSocketTimeout(this.reactorConfig.getSoTimeout());
             key.attach(dataChannel);
             dataChannel.handleIOEvent(SelectionKey.OP_CONNECT);
@@ -337,12 +330,10 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
                     final SocketChannel socketChannel,
                     final NamedEndpoint namedEndpoint,
                     final Object attachment) {
-                IOSession ioSession = new IOSessionImpl(key, socketChannel);
-                if (ioSessionDecorator != null) {
-                    ioSession = ioSessionDecorator.decorate(ioSession);
-                }
+                final IOSession ioSession = new IOSessionImpl(key, socketChannel);
                 final InternalDataChannel dataChannel = new InternalDataChannel(ioSession, namedEndpoint, sessionListener, closedSessions);
-                dataChannel.upgrade(eventHandlerFactory.createHandler(dataChannel, attachment));
+                final ProtocolIOSession protocolSession = ioSessionDecorator != null ? ioSessionDecorator.decorate(dataChannel) : dataChannel;
+                dataChannel.upgrade(eventHandlerFactory.createHandler(protocolSession, attachment));
                 dataChannel.setSocketTimeout(reactorConfig.getSoTimeout());
                 return dataChannel;
             }


[httpcomponents-core] 01/02: Improved exception handling in the async HTTP protocol negotiators

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

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

commit 5c28eb27ee7504386aa788fbd688d5f885b6e68f
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Fri Jun 7 11:52:52 2019 +0200

    Improved exception handling in the async HTTP protocol negotiators
---
 .../impl/nio/ClientHttpProtocolNegotiator.java     | 71 ++++++++--------------
 .../impl/nio/ServerHttpProtocolNegotiator.java     | 32 +++++++---
 2 files changed, 47 insertions(+), 56 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
index 6b3a97e..3dc0fc1 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
@@ -32,25 +32,21 @@ import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.net.ssl.SSLSession;
 
 import org.apache.hc.core5.annotation.Internal;
-import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.EndpointDetails;
 import org.apache.hc.core5.http.ProtocolVersion;
 import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer;
 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
 import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
-import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
-import org.apache.hc.core5.http.nio.command.RequestExecutionCommand;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.ssl.ApplicationProtocols;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.io.SocketTimeoutExceptionFactory;
-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.TlsDetails;
@@ -77,6 +73,7 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
     private final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory;
     private final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory;
     private final HttpVersionPolicy versionPolicy;
+    private final AtomicReference<HttpConnectionEventHandler> protocolHandlerRef;
 
     private volatile ByteBuffer preface;
 
@@ -89,28 +86,31 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
         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.protocolHandlerRef = new AtomicReference<>(null);
     }
 
     private void startHttp1(final IOSession session) {
         final ClientHttp1StreamDuplexer http1StreamHandler = http1StreamHandlerFactory.create(ioSession);
-        final ClientHttp1IOEventHandler newHandler = new ClientHttp1IOEventHandler(http1StreamHandler);
+        final HttpConnectionEventHandler protocolHandler = new ClientHttp1IOEventHandler(http1StreamHandler);
         try {
-            ioSession.upgrade(newHandler);
-            newHandler.connected(session);
+            ioSession.upgrade(protocolHandler);
+            protocolHandlerRef.set(protocolHandler);
+            protocolHandler.connected(session);
         } catch (final Exception ex) {
-            newHandler.exception(session, ex);
+            protocolHandler.exception(session, ex);
             session.close(CloseMode.IMMEDIATE);
         }
     }
 
     private void startHttp2(final IOSession session) {
         final ClientHttp2StreamMultiplexer streamMultiplexer = http2StreamHandlerFactory.create(ioSession);
-        final IOEventHandler newHandler = new ClientHttp2IOEventHandler(streamMultiplexer);
+        final HttpConnectionEventHandler protocolHandler = new ClientHttp2IOEventHandler(streamMultiplexer);
         try {
-            ioSession.upgrade(newHandler);
-            newHandler.connected(session);
+            ioSession.upgrade(protocolHandler);
+            protocolHandlerRef.set(protocolHandler);
+            protocolHandler.connected(session);
         } catch (final Exception ex) {
-            newHandler.exception(session, ex);
+            protocolHandler.exception(session, ex);
             session.close(CloseMode.IMMEDIATE);
         }
     }
@@ -172,43 +172,18 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public void exception(final IOSession session, final Exception cause) {
-        try {
-            for (;;) {
-                final Command command = ioSession.poll();
-                if (command != null) {
-                    if (command instanceof RequestExecutionCommand) {
-                        final RequestExecutionCommand executionCommand = (RequestExecutionCommand) command;
-                        final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
-                        exchangeHandler.failed(cause);
-                        exchangeHandler.releaseResources();
-                    } else {
-                        command.cancel();
-                    }
-                } else {
-                    break;
-                }
-            }
-        } finally {
-            session.close(CloseMode.IMMEDIATE);
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        if (protocolHandler != null) {
+            protocolHandler.exception(session, cause);
         }
+        session.close(CloseMode.IMMEDIATE);
     }
 
     @Override
     public void disconnected(final IOSession session) {
-        for (;;) {
-            final Command command = ioSession.poll();
-            if (command != null) {
-                if (command instanceof RequestExecutionCommand) {
-                    final RequestExecutionCommand executionCommand = (RequestExecutionCommand) command;
-                    final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
-                    exchangeHandler.failed(new ConnectionClosedException());
-                    exchangeHandler.releaseResources();
-                } else {
-                    command.cancel();
-                }
-            } else {
-                break;
-            }
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.getAndSet(null);
+        if (protocolHandler != null) {
+            protocolHandler.disconnected(ioSession);
         }
     }
 
@@ -220,7 +195,8 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public EndpointDetails getEndpointDetails() {
-        return null;
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        return protocolHandler != null ? protocolHandler.getEndpointDetails() : null;
     }
 
     @Override
@@ -235,7 +211,8 @@ public class ClientHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public ProtocolVersion getProtocolVersion() {
-        return null;
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        return protocolHandler != null ? protocolHandler.getProtocolVersion() : null;
     }
 
     @Override
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
index 165f10d..84d6714 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.http2.impl.nio;
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.net.ssl.SSLSession;
 
@@ -47,7 +48,6 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.ssl.ApplicationProtocols;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.io.SocketTimeoutExceptionFactory;
-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.TlsDetails;
@@ -71,6 +71,7 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
     private final ServerHttp2StreamMultiplexerFactory http2StreamHandlerFactory;
     private final HttpVersionPolicy versionPolicy;
     private final ByteBuffer bytebuf;
+    private final AtomicReference<HttpConnectionEventHandler> protocolHandlerRef;
 
     private volatile boolean expectValidH2Preface;
 
@@ -84,6 +85,7 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
         this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
         this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
         this.bytebuf = ByteBuffer.allocate(1024);
+        this.protocolHandlerRef = new AtomicReference<>(null);
     }
 
     @Override
@@ -107,7 +109,9 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                     final ServerHttp1StreamDuplexer http1StreamHandler = http1StreamHandlerFactory.create(
                             tlsDetails != null ? URIScheme.HTTPS.id : URIScheme.HTTP.id,
                             ioSession);
-                    ioSession.upgrade(new ServerHttp1IOEventHandler(http1StreamHandler));
+                    final HttpConnectionEventHandler protocolHandler = new ServerHttp1IOEventHandler(http1StreamHandler);
+                    ioSession.upgrade(protocolHandler);
+                    protocolHandlerRef.set(protocolHandler);
                     http1StreamHandler.onConnect(null);
                     break;
             }
@@ -140,7 +144,9 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                 }
                 if (validH2Preface) {
                     final ServerHttp2StreamMultiplexer http2StreamHandler = http2StreamHandlerFactory.create(ioSession);
-                    ioSession.upgrade(new ServerHttp2IOEventHandler(http2StreamHandler));
+                    final HttpConnectionEventHandler protocolHandler = new ServerHttp2IOEventHandler(http2StreamHandler);
+                    ioSession.upgrade(protocolHandler);
+                    protocolHandlerRef.set(protocolHandler);
                     http2StreamHandler.onConnect(bytebuf.hasRemaining() ? bytebuf : null);
                     http2StreamHandler.onInput();
                 } else {
@@ -148,7 +154,9 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
                     final ServerHttp1StreamDuplexer http1StreamHandler = http1StreamHandlerFactory.create(
                             tlsDetails != null ? URIScheme.HTTPS.id : URIScheme.HTTP.id,
                             ioSession);
-                    ioSession.upgrade(new ServerHttp1IOEventHandler(http1StreamHandler));
+                    final HttpConnectionEventHandler protocolHandler = new ServerHttp1IOEventHandler(http1StreamHandler);
+                    ioSession.upgrade(protocolHandler);
+                    protocolHandlerRef.set(protocolHandler);
                     bytebuf.rewind();
                     http1StreamHandler.onConnect(bytebuf);
                     http1StreamHandler.onInput();
@@ -174,15 +182,19 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public void exception(final IOSession session, final Exception cause) {
-        final IOEventHandler sessionHandler = ioSession.getHandler();
-        if (sessionHandler != null) {
-            sessionHandler.exception(session, cause);
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        if (protocolHandler != null) {
+            protocolHandler.exception(session, cause);
         }
         session.close(CloseMode.IMMEDIATE);
     }
 
     @Override
     public void disconnected(final IOSession session) {
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.getAndSet(null);
+        if (protocolHandler != null) {
+            protocolHandler.disconnected(ioSession);
+        }
     }
 
     @Override
@@ -193,7 +205,8 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public EndpointDetails getEndpointDetails() {
-        return null;
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        return protocolHandler != null ? protocolHandler.getEndpointDetails() : null;
     }
 
     @Override
@@ -208,7 +221,8 @@ public class ServerHttpProtocolNegotiator implements HttpConnectionEventHandler
 
     @Override
     public ProtocolVersion getProtocolVersion() {
-        return null;
+        final HttpConnectionEventHandler protocolHandler = protocolHandlerRef.get();
+        return protocolHandler != null ? protocolHandler.getProtocolVersion() : null;
     }
 
     @Override