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 2022/02/02 15:55:57 UTC
[httpcomponents-core] 01/01: Protocol negotiators now keep track the negotiated HTTP protocol version and can report it to the application layer; improved HTTP protocol negotiation
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit f9aa9553994de5993813188f8a421e06535b6084
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Feb 2 13:09:52 2022 +0100
Protocol negotiators now keep track the negotiated HTTP protocol version and can report it to the application layer; improved HTTP protocol negotiation
---
...a => ClientHttpProtocolNegotiationStarter.java} | 27 +++++++++-----
.../impl/nio/ClientHttpProtocolNegotiator.java | 5 ++-
.../nio/ClientHttpProtocolNegotiatorFactory.java | 3 ++
.../impl/nio/H2OnlyClientProtocolNegotiator.java | 11 +++++-
.../nio/H2OnlyServerHttpProtocolNegotiator.java | 10 ++++-
.../http2/impl/nio/ProtocolNegotiatorBase.java | 7 +++-
...a => ServerHttpProtocolNegotiationStarter.java} | 43 +++++++++++++---------
.../impl/nio/ServerHttpProtocolNegotiator.java | 9 ++---
.../nio/ServerHttpProtocolNegotiatorFactory.java | 3 ++
.../impl/nio/bootstrap/H2RequesterBootstrap.java | 4 +-
.../impl/nio/bootstrap/H2ServerBootstrap.java | 4 +-
.../apache/hc/core5/testing/nio/H2TestClient.java | 4 +-
.../apache/hc/core5/testing/nio/H2TestServer.java | 4 +-
... InternalClientProtocolNegotiationStarter.java} | 19 ++++++----
... InternalServerProtocolNegotiationStarter.java} | 22 +++++++----
.../http/impl/nio/ClientHttp1IOEventHandler.java | 8 ++++
.../http/impl/nio/ServerHttp1IOEventHandler.java | 8 ++++
.../hc/core5/reactor/InternalDataChannel.java | 6 ++-
18 files changed, 133 insertions(+), 64 deletions(-)
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiationStarter.java
similarity index 78%
copy from httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
copy to httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiationStarter.java
index e257ae9..06d0998 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiationStarter.java
@@ -32,7 +32,9 @@ import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
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.ssl.TlsStrategy;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.reactor.EndpointParameters;
@@ -43,13 +45,15 @@ import org.apache.hc.core5.util.Asserts;
import org.apache.hc.core5.util.Timeout;
/**
- * {@link ClientHttpProtocolNegotiator} factory.
+ * Client I/O event starter that prepares I/O sessions for an initial protocol handshake.
+ * This class may return a different {@link org.apache.hc.core5.reactor.IOEventHandler}
+ * implementation based on the current HTTP version policy.
*
- * @since 5.0
+ * @since 5.1
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
@Internal
-public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactory {
+public class ClientHttpProtocolNegotiationStarter implements IOEventHandlerFactory {
private final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory;
private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
@@ -57,7 +61,7 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
private final TlsStrategy tlsStrategy;
private final Timeout handshakeTimeout;
- public ClientHttpProtocolNegotiatorFactory(
+ public ClientHttpProtocolNegotiationStarter(
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory,
final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
final HttpVersionPolicy versionPolicy,
@@ -71,7 +75,7 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
}
@Override
- public ClientHttpProtocolNegotiator createHandler(final ProtocolIOSession ioSession, final Object attachment) {
+ public HttpConnectionEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
HttpVersionPolicy endpointPolicy = versionPolicy;
if (attachment instanceof EndpointParameters) {
final EndpointParameters params = (EndpointParameters) attachment;
@@ -90,11 +94,14 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
endpointPolicy = (HttpVersionPolicy) params.getAttachment();
}
}
- return new ClientHttpProtocolNegotiator(
- ioSession,
- http1StreamHandlerFactory,
- http2StreamHandlerFactory,
- endpointPolicy);
+ switch (endpointPolicy) {
+ case FORCE_HTTP_2:
+ return new H2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, false);
+ case FORCE_HTTP_1:
+ return new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession));
+ default:
+ return new ClientHttpProtocolNegotiator(ioSession, http1StreamHandlerFactory, http2StreamHandlerFactory, HttpVersionPolicy.NEGOTIATE);
+ }
}
}
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 a1a7f4b..4840450 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
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.impl.nio.BufferedData;
import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
@@ -94,7 +95,7 @@ public class ClientHttpProtocolNegotiator extends ProtocolNegotiatorBase {
private void startHttp1() throws IOException {
final ByteBuffer data = inBuf != null ? inBuf.data() : null;
- startProtocol(new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession)), data);
+ startProtocol(HttpVersion.HTTP_1_1, new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession)), data);
if (inBuf != null) {
inBuf.clear();
}
@@ -102,7 +103,7 @@ public class ClientHttpProtocolNegotiator extends ProtocolNegotiatorBase {
private void startHttp2() throws IOException {
final ByteBuffer data = inBuf != null ? inBuf.data() : null;
- startProtocol(new ClientH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data);
+ startProtocol(HttpVersion.HTTP_2, new ClientH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data);
if (inBuf != null) {
inBuf.clear();
}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
index e257ae9..2ecfde4 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
@@ -46,9 +46,12 @@ import org.apache.hc.core5.util.Timeout;
* {@link ClientHttpProtocolNegotiator} factory.
*
* @since 5.0
+ *
+ * @deprecated Use {@link ClientHttpProtocolNegotiationStarter}
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
@Internal
+@Deprecated
public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactory {
private final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory;
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
index a4f7df5..9808bfb 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
@@ -34,6 +34,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
import org.apache.hc.core5.reactor.IOSession;
import org.apache.hc.core5.reactor.ProtocolIOSession;
@@ -102,8 +104,7 @@ public class H2OnlyClientProtocolNegotiator extends ProtocolNegotiatorBase {
}
if (!preface.hasRemaining()) {
session.clearEvent(SelectionKey.OP_WRITE);
- final ClientH2StreamMultiplexer streamMultiplexer = http2StreamHandlerFactory.create(ioSession);
- startProtocol(new ClientH2IOEventHandler(streamMultiplexer), null);
+ startProtocol(HttpVersion.HTTP_2, new ClientH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), null);
preface = null;
}
}
@@ -140,6 +141,12 @@ public class H2OnlyClientProtocolNegotiator extends ProtocolNegotiatorBase {
}
@Override
+ public ProtocolVersion getProtocolVersion() {
+ final ProtocolVersion protocolVersion = super.getProtocolVersion();
+ return protocolVersion != null ? protocolVersion : HttpVersion.HTTP_2;
+ }
+
+ @Override
public String toString() {
return getClass().getName();
}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyServerHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyServerHttpProtocolNegotiator.java
index a770f01..6aa2248 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyServerHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyServerHttpProtocolNegotiator.java
@@ -33,6 +33,8 @@ import java.nio.ByteBuffer;
import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.impl.nio.BufferedData;
import org.apache.hc.core5.reactor.IOSession;
import org.apache.hc.core5.reactor.ProtocolIOSession;
@@ -90,7 +92,7 @@ public class H2OnlyServerHttpProtocolNegotiator extends ProtocolNegotiatorBase {
throw new ProtocolNegotiationException("Unexpected HTTP/2 preface");
}
}
- startProtocol(new ServerH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data.hasRemaining() ? data : null);
+ startProtocol(HttpVersion.HTTP_2, new ServerH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data.hasRemaining() ? data : null);
} else {
if (endOfStream) {
throw new ConnectionClosedException();
@@ -103,6 +105,12 @@ public class H2OnlyServerHttpProtocolNegotiator extends ProtocolNegotiatorBase {
}
@Override
+ public ProtocolVersion getProtocolVersion() {
+ final ProtocolVersion protocolVersion = super.getProtocolVersion();
+ return protocolVersion != null ? protocolVersion : HttpVersion.HTTP_2;
+ }
+
+ @Override
public String toString() {
return getClass().getName();
}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ProtocolNegotiatorBase.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ProtocolNegotiatorBase.java
index 89e787c..ccf1b92 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ProtocolNegotiatorBase.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ProtocolNegotiatorBase.java
@@ -55,6 +55,7 @@ abstract class ProtocolNegotiatorBase implements HttpConnectionEventHandler {
private final AtomicReference<HttpConnectionEventHandler> protocolHandlerRef;
private final FutureCallback<ProtocolIOSession> resultCallback;
private final AtomicBoolean completed;
+ private final AtomicReference<ProtocolVersion> negotiatedProtocolRef;
ProtocolNegotiatorBase(
final ProtocolIOSession ioSession,
@@ -63,9 +64,11 @@ abstract class ProtocolNegotiatorBase implements HttpConnectionEventHandler {
this.protocolHandlerRef = new AtomicReference<>();
this.resultCallback = resultCallback;
this.completed = new AtomicBoolean();
+ this.negotiatedProtocolRef = new AtomicReference<>();
}
- void startProtocol(final HttpConnectionEventHandler protocolHandler, final ByteBuffer data) throws IOException {
+ void startProtocol(final ProtocolVersion protocolVersion, final HttpConnectionEventHandler protocolHandler, final ByteBuffer data) throws IOException {
+ negotiatedProtocolRef.set(protocolVersion);
protocolHandlerRef.set(protocolHandler);
ioSession.upgrade(protocolHandler);
protocolHandler.connected(ioSession);
@@ -138,7 +141,7 @@ abstract class ProtocolNegotiatorBase implements HttpConnectionEventHandler {
@Override
public ProtocolVersion getProtocolVersion() {
- return null;
+ return negotiatedProtocolRef.get();
}
@Override
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiationStarter.java
similarity index 68%
copy from httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
copy to httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiationStarter.java
index e257ae9..ebc9a0f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiationStarter.java
@@ -30,9 +30,10 @@ package org.apache.hc.core5.http2.impl.nio;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.URIScheme;
-import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
+import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
+import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandler;
+import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.reactor.EndpointParameters;
@@ -43,23 +44,25 @@ import org.apache.hc.core5.util.Asserts;
import org.apache.hc.core5.util.Timeout;
/**
- * {@link ClientHttpProtocolNegotiator} factory.
+ * Server I/O event starter that prepares I/O sessions for an initial protocol handshake.
+ * This class may return a different {@link org.apache.hc.core5.reactor.IOEventHandler}
+ * implementation based on the current HTTP version policy.
*
- * @since 5.0
+ * @since 5.1
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
@Internal
-public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactory {
+public class ServerHttpProtocolNegotiationStarter implements IOEventHandlerFactory {
- private final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory;
- private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
+ private final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory;
+ private final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory;
private final HttpVersionPolicy versionPolicy;
private final TlsStrategy tlsStrategy;
private final Timeout handshakeTimeout;
- public ClientHttpProtocolNegotiatorFactory(
- final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory,
- final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
+ public ServerHttpProtocolNegotiationStarter(
+ final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory,
+ final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory,
final HttpVersionPolicy versionPolicy,
final TlsStrategy tlsStrategy,
final Timeout handshakeTimeout) {
@@ -71,16 +74,17 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
}
@Override
- public ClientHttpProtocolNegotiator createHandler(final ProtocolIOSession ioSession, final Object attachment) {
+ public HttpConnectionEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
HttpVersionPolicy endpointPolicy = versionPolicy;
+ URIScheme uriScheme = URIScheme.HTTP;
if (attachment instanceof EndpointParameters) {
final EndpointParameters params = (EndpointParameters) attachment;
if (URIScheme.HTTPS.same(params.getScheme())) {
Asserts.notNull(tlsStrategy, "TLS strategy");
- final HttpHost host = new HttpHost(params.getScheme(), params.getHostName(), params.getPort());
+ uriScheme = URIScheme.HTTPS;
tlsStrategy.upgrade(
ioSession,
- host,
+ null,
ioSession.getLocalAddress(),
ioSession.getRemoteAddress(),
params.getAttachment(),
@@ -90,11 +94,14 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
endpointPolicy = (HttpVersionPolicy) params.getAttachment();
}
}
- return new ClientHttpProtocolNegotiator(
- ioSession,
- http1StreamHandlerFactory,
- http2StreamHandlerFactory,
- endpointPolicy);
+ switch (endpointPolicy) {
+ case FORCE_HTTP_2:
+ return new H2OnlyServerHttpProtocolNegotiator(ioSession, http2StreamHandlerFactory);
+ case FORCE_HTTP_1:
+ return new ServerHttp1IOEventHandler(http1StreamHandlerFactory.create(uriScheme.id, ioSession));
+ default:
+ return new ServerHttpProtocolNegotiator(ioSession, http1StreamHandlerFactory, http2StreamHandlerFactory, HttpVersionPolicy.NEGOTIATE);
+ }
}
}
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 8d9aed2..1211aec 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
@@ -34,10 +34,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.ConnectionClosedException;
+import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.impl.nio.BufferedData;
import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandler;
-import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer;
import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
@@ -92,14 +92,13 @@ public class ServerHttpProtocolNegotiator extends ProtocolNegotiatorBase {
}
private void startHttp1(final TlsDetails tlsDetails, final ByteBuffer data) throws IOException {
- final ServerHttp1StreamDuplexer http1StreamHandler = http1StreamHandlerFactory.create(
+ startProtocol(HttpVersion.HTTP_1_1, new ServerHttp1IOEventHandler(http1StreamHandlerFactory.create(
tlsDetails != null ? URIScheme.HTTPS.id : URIScheme.HTTP.id,
- ioSession);
- startProtocol(new ServerHttp1IOEventHandler(http1StreamHandler), data);
+ ioSession)), data);
}
private void startHttp2(final ByteBuffer data) throws IOException {
- startProtocol(new ServerH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data);
+ startProtocol(HttpVersion.HTTP_2, new ServerH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data);
}
private void initialize() throws IOException {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
index e3f432c..60b634d 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
@@ -45,9 +45,12 @@ import org.apache.hc.core5.util.Timeout;
* {@link ServerHttpProtocolNegotiator} factory.
*
* @since 5.0
+ *
+ * @deprecated Use {@link ServerHttpProtocolNegotiationStarter}
*/
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
@Internal
+@Deprecated
public class ServerHttpProtocolNegotiatorFactory implements IOEventHandlerFactory {
private final ServerHttp1StreamDuplexerFactory http1StreamDuplexerFactory;
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 44adb0d..3dbb4b2 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
@@ -52,7 +52,7 @@ import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.H2Processors;
import org.apache.hc.core5.http2.impl.nio.ClientH2StreamMultiplexerFactory;
-import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiatorFactory;
+import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiationStarter;
import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
import org.apache.hc.core5.http2.nio.support.DefaultAsyncPushConsumerFactory;
import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
@@ -335,7 +335,7 @@ public class H2RequesterBootstrap {
DefaultContentLengthStrategy.INSTANCE,
http1StreamListener);
- final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttpProtocolNegotiatorFactory(
+ final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttpProtocolNegotiationStarter(
http1StreamHandlerFactory,
http2StreamHandlerFactory,
actualVersionProtocol,
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 a983611..879b87c 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
@@ -65,7 +65,7 @@ import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.H2Processors;
import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
import org.apache.hc.core5.http2.impl.nio.ServerH2StreamMultiplexerFactory;
-import org.apache.hc.core5.http2.impl.nio.ServerHttpProtocolNegotiatorFactory;
+import org.apache.hc.core5.http2.impl.nio.ServerHttpProtocolNegotiationStarter;
import org.apache.hc.core5.http2.ssl.H2ServerTlsStrategy;
import org.apache.hc.core5.net.InetAddressUtils;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
@@ -444,7 +444,7 @@ public class H2ServerBootstrap {
DefaultContentLengthStrategy.INSTANCE,
http1StreamListener);
- final IOEventHandlerFactory ioEventHandlerFactory = new ServerHttpProtocolNegotiatorFactory(
+ final IOEventHandlerFactory ioEventHandlerFactory = new ServerHttpProtocolNegotiationStarter(
http1StreamHandlerFactory,
http2StreamHandlerFactory,
actualVersionProtocol,
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestClient.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestClient.java
index 48b3682..7197ef6 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestClient.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestClient.java
@@ -88,7 +88,7 @@ public class H2TestClient extends AsyncRequester {
}
public void start(final HttpProcessor httpProcessor, final H2Config h2Config) throws IOException {
- start(new InternalClientH2EventHandlerFactory(
+ start(new InternalClientProtocolNegotiationStarter(
httpProcessor,
new DefaultAsyncPushConsumerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_2,
@@ -101,7 +101,7 @@ public class H2TestClient extends AsyncRequester {
}
public void start(final HttpProcessor httpProcessor, final Http1Config http1Config) throws IOException {
- start(new InternalClientH2EventHandlerFactory(
+ start(new InternalClientProtocolNegotiationStarter(
httpProcessor,
new DefaultAsyncPushConsumerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_1,
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
index 7707bfd..8650bb1 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
@@ -102,7 +102,7 @@ public class H2TestServer extends AsyncServer {
final HttpProcessor httpProcessor,
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
final H2Config h2Config) throws Exception {
- start(new InternalServerH2EventHandlerFactory(
+ start(new InternalServerProtocolNegotiationStarter(
httpProcessor != null ? httpProcessor : H2Processors.server(),
new DefaultAsyncResponseExchangeHandlerFactory(
registry,
@@ -130,7 +130,7 @@ public class H2TestServer extends AsyncServer {
final HttpProcessor httpProcessor,
final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator,
final Http1Config http1Config) throws Exception {
- start(new InternalServerH2EventHandlerFactory(
+ start(new InternalServerProtocolNegotiationStarter(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
new DefaultAsyncResponseExchangeHandlerFactory(
registry,
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientH2EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientProtocolNegotiationStarter.java
similarity index 86%
rename from httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientH2EventHandlerFactory.java
rename to httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientProtocolNegotiationStarter.java
index 240eddd..6be8a16 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientH2EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalClientProtocolNegotiationStarter.java
@@ -32,6 +32,7 @@ import javax.net.ssl.SSLContext;
import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.impl.HttpProcessors;
+import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
import org.apache.hc.core5.http.nio.HandlerFactory;
@@ -41,6 +42,7 @@ import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.H2Processors;
import org.apache.hc.core5.http2.impl.nio.ClientH2StreamMultiplexerFactory;
import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiator;
+import org.apache.hc.core5.http2.impl.nio.H2OnlyClientProtocolNegotiator;
import org.apache.hc.core5.reactor.IOEventHandler;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
import org.apache.hc.core5.reactor.ProtocolIOSession;
@@ -48,7 +50,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
import org.apache.hc.core5.util.Args;
-class InternalClientH2EventHandlerFactory implements IOEventHandlerFactory {
+class InternalClientProtocolNegotiationStarter implements IOEventHandlerFactory {
private final HttpProcessor httpProcessor;
private final HandlerFactory<AsyncPushConsumer> exchangeHandlerFactory;
@@ -60,7 +62,7 @@ class InternalClientH2EventHandlerFactory implements IOEventHandlerFactory {
private final SSLSessionInitializer sslSessionInitializer;
private final SSLSessionVerifier sslSessionVerifier;
- InternalClientH2EventHandlerFactory(
+ InternalClientProtocolNegotiationStarter(
final HttpProcessor httpProcessor,
final HandlerFactory<AsyncPushConsumer> exchangeHandlerFactory,
final HttpVersionPolicy versionPolicy,
@@ -97,11 +99,14 @@ class InternalClientH2EventHandlerFactory implements IOEventHandlerFactory {
h2Config,
charCodingConfig,
LoggingH2StreamListener.INSTANCE);
- return new ClientHttpProtocolNegotiator(
- ioSession,
- http1StreamHandlerFactory,
- http2StreamHandlerFactory,
- versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE);
+ switch (versionPolicy) {
+ case FORCE_HTTP_2:
+ return new H2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, false);
+ case FORCE_HTTP_1:
+ return new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession));
+ default:
+ return new ClientHttpProtocolNegotiator(ioSession, http1StreamHandlerFactory, http2StreamHandlerFactory, HttpVersionPolicy.NEGOTIATE);
+ }
}
}
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerH2EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerProtocolNegotiationStarter.java
similarity index 84%
rename from httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerH2EventHandlerFactory.java
rename to httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerProtocolNegotiationStarter.java
index 6aefbf0..868f16f 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerH2EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerProtocolNegotiationStarter.java
@@ -29,9 +29,11 @@ package org.apache.hc.core5.testing.nio;
import javax.net.ssl.SSLContext;
+import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.impl.HttpProcessors;
+import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandler;
import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.HandlerFactory;
@@ -39,6 +41,7 @@ import org.apache.hc.core5.http.protocol.HttpProcessor;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.H2Processors;
+import org.apache.hc.core5.http2.impl.nio.H2OnlyServerHttpProtocolNegotiator;
import org.apache.hc.core5.http2.impl.nio.ServerH2StreamMultiplexerFactory;
import org.apache.hc.core5.http2.impl.nio.ServerHttpProtocolNegotiator;
import org.apache.hc.core5.reactor.IOEventHandler;
@@ -48,7 +51,7 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
import org.apache.hc.core5.util.Args;
-class InternalServerH2EventHandlerFactory implements IOEventHandlerFactory {
+class InternalServerProtocolNegotiationStarter implements IOEventHandlerFactory {
private final HttpProcessor httpProcessor;
private final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory;
@@ -60,7 +63,7 @@ class InternalServerH2EventHandlerFactory implements IOEventHandlerFactory {
private final SSLSessionInitializer sslSessionInitializer;
private final SSLSessionVerifier sslSessionVerifier;
- public InternalServerH2EventHandlerFactory(
+ public InternalServerProtocolNegotiationStarter(
final HttpProcessor httpProcessor,
final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory,
final HttpVersionPolicy versionPolicy,
@@ -98,11 +101,16 @@ class InternalServerH2EventHandlerFactory implements IOEventHandlerFactory {
h2Config,
charCodingConfig,
LoggingH2StreamListener.INSTANCE);
- return new ServerHttpProtocolNegotiator(
- ioSession,
- http1StreamHandlerFactory,
- http2StreamHandlerFactory,
- versionPolicy);
+ switch (versionPolicy) {
+ case FORCE_HTTP_2:
+ return new H2OnlyServerHttpProtocolNegotiator(ioSession, http2StreamHandlerFactory);
+ case FORCE_HTTP_1:
+ return new ServerHttp1IOEventHandler(http1StreamHandlerFactory.create(
+ sslContext != null ? URIScheme.HTTPS.id : URIScheme.HTTP.id,
+ ioSession));
+ default:
+ return new ServerHttpProtocolNegotiator(ioSession, http1StreamHandlerFactory, http2StreamHandlerFactory, HttpVersionPolicy.NEGOTIATE);
+ }
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandler.java
index 0ed0a6e..7454a35 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandler.java
@@ -27,6 +27,8 @@
package org.apache.hc.core5.http.impl.nio;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.net.InetAddressUtils;
/**
@@ -54,5 +56,11 @@ public class ClientHttp1IOEventHandler extends AbstractHttp1IOEventHandler {
return buf.toString();
}
+ @Override
+ public ProtocolVersion getProtocolVersion() {
+ final ProtocolVersion protocolVersion = super.getProtocolVersion();
+ return protocolVersion != null ? protocolVersion : HttpVersion.HTTP_1_1;
+ }
+
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandler.java
index 2398e3d..28b3052 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandler.java
@@ -27,6 +27,8 @@
package org.apache.hc.core5.http.impl.nio;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.net.InetAddressUtils;
/**
@@ -54,4 +56,10 @@ public class ServerHttp1IOEventHandler extends AbstractHttp1IOEventHandler {
return buf.toString();
}
+ @Override
+ public ProtocolVersion getProtocolVersion() {
+ final ProtocolVersion protocolVersion = super.getProtocolVersion();
+ return protocolVersion != null ? protocolVersion : HttpVersion.HTTP_1_1;
+ }
+
}
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 abf93fd..34e31c4 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
@@ -61,6 +61,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
private final Queue<InternalDataChannel> closedSessions;
private final AtomicReference<SSLIOSession> tlsSessionRef;
private final AtomicReference<IOSession> currentSessionRef;
+ private final AtomicReference<IOEventHandler> eventHandlerRef;
private final AtomicBoolean closed;
InternalDataChannel(
@@ -77,6 +78,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
this.tlsSessionRef = new AtomicReference<>();
this.currentSessionRef = new AtomicReference<>(
ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession);
+ this.eventHandlerRef = new AtomicReference<>();
this.closed = new AtomicBoolean(false);
}
@@ -92,14 +94,14 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
@Override
public IOEventHandler getHandler() {
- final IOSession currentSession = currentSessionRef.get();
- return currentSession.getHandler();
+ return eventHandlerRef.get();
}
@Override
public void upgrade(final IOEventHandler handler) {
final IOSession currentSession = currentSessionRef.get();
currentSession.upgrade(handler);
+ eventHandlerRef.set(handler);
}
private IOEventHandler ensureHandler(final IOSession session) {