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 2023/12/13 08:24:00 UTC
(httpcomponents-core) 33/37: HTTPCORE-756: Support for the effective HTTP/1.x protocol level config parameter; HTTP/1.1 endpoints to signal their actual supported protocol level (the minor version in HTTP/1.x) in the message control data as per RFC 9110 section 6.2
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 51f3be8b9e203f5b923733d44909fd9b15179a31
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Tue Oct 10 11:38:42 2023 +0200
HTTPCORE-756: Support for the effective HTTP/1.x protocol level config parameter; HTTP/1.1 endpoints to signal their actual supported protocol level (the minor version in HTTP/1.x) in the message control data as per RFC 9110 section 6.2
---
.../impl/nio/bootstrap/H2ServerBootstrap.java | 4 +-
.../core5/testing/classic/ClassicTestClient.java | 2 +-
.../InternalServerHttp1EventHandlerFactory.java | 2 +-
.../testing/classic/ClassicIntegrationTest.java | 62 ++++++++++------------
.../testing/framework/TestTestingFramework.java | 27 ----------
.../hc/core5/testing/nio/Http1IntegrationTest.java | 62 ++++++++--------------
.../apache/hc/core5/http/config/Http1Config.java | 39 ++++++++++++--
.../http/impl/bootstrap/AsyncServerBootstrap.java | 6 +--
.../http/impl/bootstrap/RequesterBootstrap.java | 13 ++++-
.../core5/http/impl/bootstrap/ServerBootstrap.java | 3 +-
.../core5/http/impl/io/AbstractMessageParser.java | 21 ++++----
.../http/impl/io/DefaultBHttpClientConnection.java | 2 +-
.../io/DefaultBHttpClientConnectionFactory.java | 6 ++-
.../http/impl/io/DefaultBHttpServerConnection.java | 2 +-
.../io/DefaultBHttpServerConnectionFactory.java | 6 ++-
.../http/impl/io/DefaultHttpRequestParser.java | 30 ++++++-----
.../impl/io/DefaultHttpRequestParserFactory.java | 32 ++++++++++-
.../http/impl/io/DefaultHttpRequestWriter.java | 33 ++++++++----
.../impl/io/DefaultHttpRequestWriterFactory.java | 23 ++++++--
.../http/impl/io/DefaultHttpResponseParser.java | 28 +++++-----
.../impl/io/DefaultHttpResponseParserFactory.java | 32 ++++++++++-
.../http/impl/io/DefaultHttpResponseWriter.java | 33 ++++++++----
.../impl/io/DefaultHttpResponseWriterFactory.java | 23 ++++++--
.../hc/core5/http/impl/io/HttpRequestExecutor.java | 42 +++++++++++----
.../apache/hc/core5/http/impl/io/HttpService.java | 49 ++++++++++++++---
.../core5/http/impl/nio/AbstractMessageParser.java | 37 ++++++-------
.../impl/nio/ClientHttp1StreamDuplexerFactory.java | 4 +-
.../http/impl/nio/ClientHttp1StreamHandler.java | 16 ++++--
.../http/impl/nio/DefaultHttpRequestParser.java | 45 ++++++++++------
.../impl/nio/DefaultHttpRequestParserFactory.java | 2 +-
.../http/impl/nio/DefaultHttpRequestWriter.java | 29 ++++++++--
.../impl/nio/DefaultHttpRequestWriterFactory.java | 23 ++++++--
.../http/impl/nio/DefaultHttpResponseParser.java | 39 +++++++++-----
.../impl/nio/DefaultHttpResponseParserFactory.java | 2 +-
.../http/impl/nio/DefaultHttpResponseWriter.java | 29 ++++++++--
.../impl/nio/DefaultHttpResponseWriterFactory.java | 23 ++++++--
.../http/impl/nio/ServerHttp1StreamDuplexer.java | 4 ++
.../impl/nio/ServerHttp1StreamDuplexerFactory.java | 4 +-
.../http/impl/nio/ServerHttp1StreamHandler.java | 14 +++--
.../hc/core5/http/io/HttpMessageParserFactory.java | 8 +++
40 files changed, 578 insertions(+), 283 deletions(-)
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 d60f84276..c7486c318 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
@@ -409,8 +409,8 @@ public class H2ServerBootstrap {
http1Config != null ? http1Config : Http1Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
- DefaultHttpRequestParserFactory.INSTANCE,
- DefaultHttpResponseWriterFactory.INSTANCE,
+ new DefaultHttpRequestParserFactory(http1Config),
+ new DefaultHttpResponseWriterFactory(http1Config),
DefaultContentLengthStrategy.INSTANCE,
DefaultContentLengthStrategy.INSTANCE,
http1StreamListener);
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestClient.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestClient.java
index efb1730cd..d2951a73d 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestClient.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestClient.java
@@ -82,7 +82,7 @@ public class ClassicTestClient {
public void start(final HttpProcessor httpProcessor) {
if (requesterRef.get() == null) {
final HttpRequestExecutor requestExecutor = new HttpRequestExecutor(
- HttpRequestExecutor.DEFAULT_WAIT_FOR_CONTINUE,
+ Http1Config.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
LoggingHttp1StreamListener.INSTANCE);
final StrictConnPool<HttpHost, HttpClientConnection> connPool = new StrictConnPool<>(
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
index de55f629e..c7487ec62 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/InternalServerHttp1EventHandlerFactory.java
@@ -95,7 +95,7 @@ class InternalServerHttp1EventHandlerFactory implements IOEventHandlerFactory {
this.sslSessionInitializer = sslSessionInitializer;
this.sslSessionVerifier = sslSessionVerifier;
this.requestParserFactory = new DefaultHttpRequestParserFactory(this.http1Config);
- this.responseWriterFactory = DefaultHttpResponseWriterFactory.INSTANCE;
+ this.responseWriterFactory = new DefaultHttpResponseWriterFactory(this.http1Config);
}
protected ServerHttp1StreamDuplexer createServerHttp1StreamDuplexer(
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
index fcfa8f389..f6f83bcfa 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
@@ -49,6 +49,7 @@ import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.URIScheme;
import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
@@ -279,9 +280,6 @@ public abstract class ClassicIntegrationTest {
final byte[] data = EntityUtils.toByteArray(entity);
response.setEntity(new ByteArrayEntity(data, null));
}
- if (HttpVersion.HTTP_1_0.equals(request.getVersion())) {
- response.addHeader("Version", "1.0");
- }
});
server.start();
@@ -298,10 +296,6 @@ public abstract class ClassicIntegrationTest {
post.setEntity(new ByteArrayEntity(data, null));
try (final ClassicHttpResponse response = client.execute(host, post, context)) {
- Assertions.assertEquals(HttpVersion.HTTP_1_1, response.getVersion());
- final Header h1 = response.getFirstHeader("Version");
- Assertions.assertNotNull(h1);
- Assertions.assertEquals("1.0", h1.getValue());
final byte[] received = EntityUtils.toByteArray(response.getEntity());
final byte[] expected = testData.get(r);
@@ -313,6 +307,32 @@ public abstract class ClassicIntegrationTest {
}
}
+ /**
+ * This test case ensures that HTTP/1.1 features are disabled when executing
+ * HTTP/1.0 compatible requests.
+ */
+ @Test
+ public void testHTTP11FeaturesDisabledWithHTTP10Requests() throws Exception {
+ final ClassicTestServer server = testResources.server();
+ final ClassicTestClient client = testResources.client();
+
+ server.start();
+ client.start();
+
+ final HttpCoreContext context = HttpCoreContext.create();
+ final HttpHost host = new HttpHost(scheme.id, "localhost", server.getPort());
+
+ final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
+ post.setVersion(HttpVersion.HTTP_1_0);
+ post.setEntity(new ByteArrayEntity(new byte[] {'a', 'b', 'c'}, null, true));
+
+ Assertions.assertThrows(ProtocolException.class, () -> {
+ try (final ClassicHttpResponse response = client.execute(host, post, context)) {
+ EntityUtils.consume(response.getEntity());
+ }
+ });
+ }
+
/**
* This test case executes a series of simple POST requests using
* the 'expect: continue' handshake.
@@ -690,34 +710,6 @@ public abstract class ClassicIntegrationTest {
}
}
- @Test
- public void testAbsentHostHeader() throws Exception {
- final ClassicTestServer server = testResources.server();
- final ClassicTestClient client = testResources.client();
-
- // Initialize the server-side request handler
- server.registerHandler("*", (request, response, context) -> response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII)));
-
- server.start();
- client.start(new DefaultHttpProcessor(RequestContent.INSTANCE, new RequestConnControl()));
-
- final HttpCoreContext context = HttpCoreContext.create();
- final HttpHost host = new HttpHost(scheme.id, "localhost", server.getPort());
-
- final BasicClassicHttpRequest get1 = new BasicClassicHttpRequest(Method.GET, "/");
- get1.setVersion(HttpVersion.HTTP_1_0);
- try (final ClassicHttpResponse response1 = client.execute(host, get1, context)) {
- Assertions.assertEquals(200, response1.getCode());
- EntityUtils.consume(response1.getEntity());
- }
-
- final BasicClassicHttpRequest get2 = new BasicClassicHttpRequest(Method.GET, "/");
- try (final ClassicHttpResponse response2 = client.execute(host, get2, context)) {
- Assertions.assertEquals(400, response2.getCode());
- EntityUtils.consume(response2.getEntity());
- }
- }
-
@Test
public void testHeaderTooLarge() throws Exception {
final ClassicTestServer server = testResources.server();
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
index dfb09be96..533b5644d 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/framework/TestTestingFramework.java
@@ -33,7 +33,6 @@ import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.HEADERS;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.METHOD;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.NAME;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.PATH;
-import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.PROTOCOL_VERSION;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.QUERY;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.REQUEST;
import static org.apache.hc.core5.testing.framework.ClientPOJOAdapter.RESPONSE;
@@ -46,8 +45,6 @@ import java.util.Map;
import java.util.Set;
import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
@@ -665,30 +662,6 @@ public class TestTestingFramework {
Assertions.assertThrows(TestingFrameworkException.class, () -> framework.runTests());
}
- @Test
- public void changeProtocolVersion() throws Exception {
- final ClientTestingAdapter adapter = new ClassicTestClientTestingAdapter() {
- @Override
- public Map<String, Object> execute(
- final String defaultURI,
- final Map<String, Object> request,
- final TestingFrameworkRequestHandler requestHandler,
- final Map<String, Object> responseExpectations) throws TestingFrameworkException {
- // change the request from what is expected.
- final ProtocolVersion protocolVersion = (ProtocolVersion) request.get(PROTOCOL_VERSION);
- Assertions.assertNotNull(protocolVersion);
- request.put(PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
- return super.execute(defaultURI, request, requestHandler, responseExpectations);
- }
- };
-
- final TestingFramework framework = newFrameworkAndSetAdapter(adapter);
-
- framework.addTest();
-
- Assertions.assertThrows(TestingFrameworkException.class, () -> framework.runTests());
- }
-
@Test
public void changeResponseExpectationsFails() throws Exception {
final ClientTestingAdapter adapter = new ClientTestingAdapter() {
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 46951ffd1..03459ee13 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -101,6 +101,7 @@ import org.apache.hc.core5.http.nio.NHttpMessageWriter;
import org.apache.hc.core5.http.nio.ResponseChannel;
import org.apache.hc.core5.http.nio.SessionOutputBuffer;
import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
+import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
@@ -522,6 +523,28 @@ public abstract class Http1IntegrationTest {
}
}
+ @Test
+ public void testHTTP11FeaturesDisabledWithHTTP10Requests() throws Exception {
+ final Http1TestServer server = resources.server();
+ final Http1TestClient client = resources.client();
+
+ server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
+ final InetSocketAddress serverEndpoint = server.start();
+
+ client.start();
+ final Future<ClientSessionEndpoint> connectFuture = client.connect(
+ "localhost", serverEndpoint.getPort(), TIMEOUT);
+ final ClientSessionEndpoint streamEndpoint = connectFuture.get();
+
+ final HttpRequest request = new BasicHttpRequest(Method.POST, createRequestURI(serverEndpoint, "/hello"));
+ request.setVersion(HttpVersion.HTTP_1_0);
+ final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
+ new BasicRequestProducer(request, new BasicAsyncEntityProducer(new byte[] {'a', 'b', 'c'}, null, true)),
+ new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+ final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, future::get);
+ Assertions.assertInstanceOf(ProtocolException.class, exception.getCause());
+ }
+
@Test
public void testNoEntityPost() throws Exception {
final Http1TestServer server = resources.server();
@@ -1604,45 +1627,6 @@ public abstract class Http1IntegrationTest {
Assertions.assertNull(result.getBody());
}
- @Test
- public void testAbsentHostHeader() throws Exception {
- final Http1TestServer server = resources.server();
- final Http1TestClient client = resources.client();
-
- server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
- final InetSocketAddress serverEndpoint = server.start();
-
- client.start(new DefaultHttpProcessor(RequestContent.INSTANCE, RequestConnControl.INSTANCE), Http1Config.DEFAULT);
-
- final Future<ClientSessionEndpoint> connectFuture = client.connect(
- "localhost", serverEndpoint.getPort(), TIMEOUT);
- final ClientSessionEndpoint streamEndpoint = connectFuture.get();
-
- final HttpRequest request1 = new BasicHttpRequest(Method.GET, createRequestURI(serverEndpoint, "/hello"));
- request1.setVersion(HttpVersion.HTTP_1_0);
- final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
- new BasicRequestProducer(request1, null),
- new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
- final Message<HttpResponse, String> result1 = future1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
- Assertions.assertNotNull(result1);
- final HttpResponse response1 = result1.getHead();
- Assertions.assertNotNull(response1);
- Assertions.assertEquals(200, response1.getCode());
- Assertions.assertEquals("Hi there", result1.getBody());
-
- final HttpRequest request2 = new BasicHttpRequest(Method.GET, createRequestURI(serverEndpoint, "/hello"));
- request2.setVersion(HttpVersion.HTTP_1_1);
- final Future<Message<HttpResponse, String>> future2 = streamEndpoint.execute(
- new BasicRequestProducer(request2, null),
- new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
- final Message<HttpResponse, String> result2 = future2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
- Assertions.assertNotNull(result2);
- final HttpResponse response2 = result2.getHead();
- Assertions.assertNotNull(response2);
- Assertions.assertEquals(400, response2.getCode());
- Assertions.assertEquals("Host header is absent", result2.getBody());
- }
-
@Test
public void testMessageWithTrailers() throws Exception {
final Http1TestServer server = resources.server();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java b/httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java
index 54e26e814..f8817469b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/config/Http1Config.java
@@ -29,6 +29,7 @@ package org.apache.hc.core5.http.config;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.Timeout;
@@ -47,6 +48,7 @@ public class Http1Config {
public static final Http1Config DEFAULT = new Builder().build();
+ private final HttpVersion version;
private final int bufferSize;
private final int chunkSizeHint;
private final Timeout waitForContinueTimeout;
@@ -55,10 +57,11 @@ public class Http1Config {
private final int maxEmptyLineCount;
private final int initialWindowSize;
- Http1Config(final int bufferSize, final int chunkSizeHint, final Timeout waitForContinueTimeout,
- final int maxLineLength, final int maxHeaderCount, final int maxEmptyLineCount,
- final int initialWindowSize) {
+ Http1Config(final HttpVersion version, final int bufferSize, final int chunkSizeHint,
+ final Timeout waitForContinueTimeout, final int maxLineLength, final int maxHeaderCount,
+ final int maxEmptyLineCount, final int initialWindowSize) {
super();
+ this.version = version;
this.bufferSize = bufferSize;
this.chunkSizeHint = chunkSizeHint;
this.waitForContinueTimeout = waitForContinueTimeout;
@@ -68,6 +71,15 @@ public class Http1Config {
this.initialWindowSize = initialWindowSize;
}
+ /**
+ * The effective protocol level expressed by the minor version of HTTP/1.x.
+ *
+ * @since 5.3
+ */
+ public HttpVersion getVersion() {
+ return version;
+ }
+
public int getBufferSize() {
return bufferSize;
}
@@ -99,7 +111,8 @@ public class Http1Config {
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
- builder.append("[bufferSize=").append(bufferSize)
+ builder.append("[version=").append(version)
+ .append(", bufferSize=").append(bufferSize)
.append(", chunkSizeHint=").append(chunkSizeHint)
.append(", waitForContinueTimeout=").append(waitForContinueTimeout)
.append(", maxLineLength=").append(maxLineLength)
@@ -116,6 +129,7 @@ public class Http1Config {
public static Http1Config.Builder copy(final Http1Config config) {
Args.notNull(config, "Config");
return new Builder()
+ .setVersion(config.getVersion())
.setBufferSize(config.getBufferSize())
.setChunkSizeHint(config.getChunkSizeHint())
.setWaitForContinueTimeout(config.getWaitForContinueTimeout())
@@ -135,6 +149,7 @@ public class Http1Config {
public static class Builder {
+ private HttpVersion version;
private int bufferSize;
private int chunkSizeHint;
private Timeout waitForContinueTimeout;
@@ -144,6 +159,7 @@ public class Http1Config {
private int initialWindowSize;
Builder() {
+ this.version = HttpVersion.HTTP_1_1;
this.bufferSize = INIT_BUF_SIZE;
this.chunkSizeHint = INIT_BUF_CHUNK;
this.waitForContinueTimeout = INIT_WAIT_FOR_CONTINUE;
@@ -153,6 +169,20 @@ public class Http1Config {
this.initialWindowSize = INIT_WINDOW_SIZE;
}
+ /**
+ * Sets the effective HTTP/1.x protocol level (as expressed by the minor version).
+ * Presently only {@link HttpVersion#HTTP_1_0} and {@link HttpVersion#HTTP_1_1} are
+ * supported.
+ *
+ * @since 5.3
+ */
+ public Builder setVersion(final HttpVersion version) {
+ Args.notNull(version, "HTTP/1 protocol version");
+ Args.check(version.getMajor() == 1, "HTTP/1 protocol version is required");
+ this.version = version;
+ return this;
+ }
+
public Builder setBufferSize(final int bufferSize) {
this.bufferSize = bufferSize;
return this;
@@ -191,6 +221,7 @@ public class Http1Config {
public Http1Config build() {
return new Http1Config(
+ version,
bufferSize,
chunkSizeHint,
waitForContinueTimeout,
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 dfbe1fabe..cb68c25f8 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
@@ -374,11 +374,11 @@ public class AsyncServerBootstrap {
final ServerHttp1StreamDuplexerFactory streamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
handlerFactory,
- http1Config != null ? http1Config : Http1Config.DEFAULT,
+ http1Config,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
connStrategy != null ? connStrategy : DefaultConnectionReuseStrategy.INSTANCE,
- DefaultHttpRequestParserFactory.INSTANCE,
- DefaultHttpResponseWriterFactory.INSTANCE,
+ new DefaultHttpRequestParserFactory(http1Config),
+ new DefaultHttpResponseWriterFactory(http1Config),
DefaultContentLengthStrategy.INSTANCE,
DefaultContentLengthStrategy.INSTANCE,
streamListener);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
index 15791af2d..a239f2032 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
@@ -65,6 +65,7 @@ import org.apache.hc.core5.util.Timeout;
public class RequesterBootstrap {
private HttpProcessor httpProcessor;
+ private Http1Config http1Config;
private ConnectionReuseStrategy connReuseStrategy;
private SocketConfig socketConfig;
private HttpConnectionFactory<? extends HttpClientConnection> connectFactory;
@@ -94,6 +95,14 @@ public class RequesterBootstrap {
return this;
}
+ /**
+ * Sets HTTP/1 protocol configuration.
+ */
+ public final RequesterBootstrap setHttp1Config(final Http1Config http1Config) {
+ this.http1Config = http1Config;
+ return this;
+ }
+
/**
* Assigns {@link ConnectionReuseStrategy} instance.
*/
@@ -179,7 +188,7 @@ public class RequesterBootstrap {
public HttpRequester create() {
final HttpRequestExecutor requestExecutor = new HttpRequestExecutor(
- HttpRequestExecutor.DEFAULT_WAIT_FOR_CONTINUE,
+ http1Config,
connReuseStrategy != null ? connReuseStrategy : DefaultConnectionReuseStrategy.INSTANCE,
streamListener);
final ManagedConnPool<HttpHost, HttpClientConnection> connPool;
@@ -209,7 +218,7 @@ public class RequesterBootstrap {
connPool,
socketConfig != null ? socketConfig : SocketConfig.DEFAULT,
connectFactory != null ? connectFactory : new DefaultBHttpClientConnectionFactory(
- Http1Config.DEFAULT, CharCodingConfig.DEFAULT),
+ http1Config, CharCodingConfig.DEFAULT),
sslSocketFactory,
sslSetupHandler != null ? sslSetupHandler : new DefaultTlsSetupHandler(),
sslSessionVerifier,
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
index d2b16d847..f52741c4a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
@@ -140,7 +140,7 @@ public class ServerBootstrap {
}
/**
- * Sets connection configuration.
+ * Sets HTTP/1 protocol configuration.
*/
public final ServerBootstrap setHttp1Config(final Http1Config http1Config) {
this.http1Config = http1Config;
@@ -380,6 +380,7 @@ public class ServerBootstrap {
final HttpService httpService = new HttpService(
this.httpProcessor != null ? this.httpProcessor : HttpProcessors.server(),
requestHandler,
+ this.http1Config,
this.connStrategy != null ? this.connStrategy : DefaultConnectionReuseStrategy.INSTANCE,
this.streamListener);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/AbstractMessageParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/AbstractMessageParser.java
index 43329b2ce..cd3482bd5 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/AbstractMessageParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/AbstractMessageParser.java
@@ -65,24 +65,25 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements Ht
private T message;
/**
- * Creates new instance of AbstractMessageParser.
- *
- * @param lineParser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used.
- * @param http1Config the message http1Config. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
*/
- public AbstractMessageParser(final LineParser lineParser, final Http1Config http1Config) {
+ public AbstractMessageParser(final Http1Config http1Config, final LineParser lineParser) {
super();
- this.lineParser = lineParser != null ? lineParser : LazyLineParser.INSTANCE;
this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
+ this.lineParser = lineParser != null ? lineParser : LazyLineParser.INSTANCE;
this.headerLines = new ArrayList<>();
this.headLine = new CharArrayBuffer(128);
this.state = HEAD_LINE;
}
+ /**
+ * @deprecated Use {@link #AbstractMessageParser(Http1Config, LineParser)}
+ */
+ @Deprecated
+ public AbstractMessageParser(final LineParser lineParser, final Http1Config http1Config) {
+ this(http1Config, lineParser);
+ }
+
LineParser getLineParser() {
return this.lineParser;
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
index 9fd4cec94..34e087e2a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
@@ -108,7 +108,7 @@ public class DefaultBHttpClientConnection extends BHttpConnectionBase
this.requestWriter = (requestWriterFactory != null ? requestWriterFactory :
DefaultHttpRequestWriterFactory.INSTANCE).create();
this.responseParser = (responseParserFactory != null ? responseParserFactory :
- DefaultHttpResponseParserFactory.INSTANCE).create(http1Config);
+ DefaultHttpResponseParserFactory.INSTANCE).create();
this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
DefaultContentLengthStrategy.INSTANCE;
this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnectionFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnectionFactory.java
index c2becd2a0..85d02b267 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnectionFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnectionFactory.java
@@ -73,8 +73,10 @@ public class DefaultBHttpClientConnectionFactory
this.incomingContentStrategy = incomingContentStrategy;
this.outgoingContentStrategy = outgoingContentStrategy;
this.responseOutOfOrderStrategy = responseOutOfOrderStrategy;
- this.requestWriterFactory = requestWriterFactory;
- this.responseParserFactory = responseParserFactory;
+ this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory :
+ new DefaultHttpRequestWriterFactory(this.http1Config) ;
+ this.responseParserFactory = responseParserFactory != null ? responseParserFactory :
+ new DefaultHttpResponseParserFactory(this.http1Config);
}
public DefaultBHttpClientConnectionFactory(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnection.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnection.java
index 8fe324f8b..aa01055e3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnection.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnection.java
@@ -95,7 +95,7 @@ public class DefaultBHttpServerConnection extends BHttpConnectionBase implements
super(http1Config, charDecoder, charEncoder);
this.scheme = scheme;
this.requestParser = (requestParserFactory != null ? requestParserFactory :
- DefaultHttpRequestParserFactory.INSTANCE).create(http1Config);
+ DefaultHttpRequestParserFactory.INSTANCE).create();
this.responseWriter = (responseWriterFactory != null ? responseWriterFactory :
DefaultHttpResponseWriterFactory.INSTANCE).create();
this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnectionFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnectionFactory.java
index 8a67f1ed1..56d5c8ece 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnectionFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpServerConnectionFactory.java
@@ -72,8 +72,10 @@ public class DefaultBHttpServerConnectionFactory implements HttpConnectionFactor
this.charCodingConfig = charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT;
this.incomingContentStrategy = incomingContentStrategy;
this.outgoingContentStrategy = outgoingContentStrategy;
- this.requestParserFactory = requestParserFactory;
- this.responseWriterFactory = responseWriterFactory;
+ this.requestParserFactory = requestParserFactory != null ? requestParserFactory :
+ new DefaultHttpRequestParserFactory(this.http1Config);
+ this.responseWriterFactory = responseWriterFactory != null ? responseWriterFactory :
+ new DefaultHttpResponseWriterFactory(this.http1Config);
}
public DefaultBHttpServerConnectionFactory(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParser.java
index b5acd53cd..19a1ecedb 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParser.java
@@ -52,37 +52,39 @@ public class DefaultHttpRequestParser extends AbstractMessageParser<ClassicHttpR
private final HttpRequestFactory<ClassicHttpRequest> requestFactory;
/**
- * Creates new instance of DefaultHttpRequestParser.
- *
- * @param lineParser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used.
- * @param requestFactory the response factory. If {@code null}
- * {@link DefaultClassicHttpRequestFactory#INSTANCE} will be used.
- * @param http1Config the message http1Config. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
*/
+ public DefaultHttpRequestParser(
+ final Http1Config http1Config,
+ final LineParser lineParser,
+ final HttpRequestFactory<ClassicHttpRequest> requestFactory) {
+ super(http1Config, lineParser);
+ this.requestFactory = requestFactory != null ? requestFactory : DefaultClassicHttpRequestFactory.INSTANCE;
+ }
+
+ /**
+ * @deprecated Use {@link #DefaultHttpRequestParser(Http1Config, LineParser, HttpRequestFactory)}
+ */
+ @Deprecated
public DefaultHttpRequestParser(
final LineParser lineParser,
final HttpRequestFactory<ClassicHttpRequest> requestFactory,
final Http1Config http1Config) {
- super(lineParser, http1Config);
- this.requestFactory = requestFactory != null ? requestFactory : DefaultClassicHttpRequestFactory.INSTANCE;
+ this(http1Config, lineParser, requestFactory);
}
/**
* @since 4.3
*/
public DefaultHttpRequestParser(final Http1Config http1Config) {
- this(null, null, http1Config);
+ this(http1Config, null, null);
}
/**
* @since 4.3
*/
public DefaultHttpRequestParser() {
- this(Http1Config.DEFAULT);
+ this(Http1Config.DEFAULT, null, null);
}
@Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParserFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParserFactory.java
index a2cbb983e..ebace6063 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParserFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestParserFactory.java
@@ -47,23 +47,51 @@ public class DefaultHttpRequestParserFactory implements HttpMessageParserFactory
public static final DefaultHttpRequestParserFactory INSTANCE = new DefaultHttpRequestParserFactory();
+ private final Http1Config http1Config;
private final LineParser lineParser;
private final HttpRequestFactory<ClassicHttpRequest> requestFactory;
- public DefaultHttpRequestParserFactory(final LineParser lineParser,
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestParserFactory(
+ final Http1Config http1Config,
+ final LineParser lineParser,
final HttpRequestFactory<ClassicHttpRequest> requestFactory) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineParser = lineParser != null ? lineParser : LazyLineParser.INSTANCE;
this.requestFactory = requestFactory != null ? requestFactory : DefaultClassicHttpRequestFactory.INSTANCE;
}
+ public DefaultHttpRequestParserFactory(final LineParser lineParser,
+ final HttpRequestFactory<ClassicHttpRequest> requestFactory) {
+ this(null, lineParser, requestFactory);
+ }
+
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestParserFactory(final Http1Config http1Config) {
+ this(http1Config, null, null);
+ }
+
public DefaultHttpRequestParserFactory() {
this(null, null);
}
+ /**
+ * @deprecated Use {@link #create()}
+ */
+ @Deprecated
@Override
public HttpMessageParser<ClassicHttpRequest> create(final Http1Config http1Config) {
- return new DefaultHttpRequestParser(this.lineParser, this.requestFactory, http1Config);
+ return new DefaultHttpRequestParser(http1Config, this.lineParser, this.requestFactory);
+ }
+
+ @Override
+ public HttpMessageParser<ClassicHttpRequest> create() {
+ return new DefaultHttpRequestParser(this.http1Config, this.lineParser, this.requestFactory);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriter.java
index 5aac8da08..c5afc4fd0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriter.java
@@ -30,8 +30,9 @@ package org.apache.hc.core5.http.impl.io;
import java.io.IOException;
import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.message.RequestLine;
import org.apache.hc.core5.util.CharArrayBuffer;
@@ -44,29 +45,41 @@ import org.apache.hc.core5.util.CharArrayBuffer;
*/
public class DefaultHttpRequestWriter extends AbstractMessageWriter<ClassicHttpRequest> {
+ private final Http1Config http1Config;
+
/**
- * Creates an instance of DefaultHttpRequestWriter.
- *
- * @param formatter the line formatter If {@code null}
- * {@link org.apache.hc.core5.http.message.BasicLineFormatter#INSTANCE}
- * will be used.
+ * @since 5.3
*/
- public DefaultHttpRequestWriter(final LineFormatter formatter) {
+ public DefaultHttpRequestWriter(final Http1Config http1Config, final LineFormatter formatter) {
super(formatter);
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
+ }
+
+ public DefaultHttpRequestWriter(final LineFormatter formatter) {
+ this(null, formatter);
}
public DefaultHttpRequestWriter() {
- this(null);
+ this(null, null);
+ }
+
+ /**
+ * Determines the HTTP protocol version to be communicated to the opposite
+ * endpoint in the message header.
+ *
+ * @since 5.3
+ */
+ protected HttpVersion protocolVersion(final HttpRequest message) {
+ return http1Config.getVersion();
}
@Override
protected void writeHeadLine(
final ClassicHttpRequest message, final CharArrayBuffer lineBuf) throws IOException {
- final ProtocolVersion transportVersion = message.getVersion();
getLineFormatter().formatRequestLine(lineBuf, new RequestLine(
message.getMethod(),
message.getRequestUri(),
- transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1));
+ protocolVersion(message)));
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriterFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriterFactory.java
index b377ccc28..c38d4b377 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriterFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpRequestWriterFactory.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.http.impl.io;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.io.HttpMessageWriter;
import org.apache.hc.core5.http.io.HttpMessageWriterFactory;
import org.apache.hc.core5.http.message.BasicLineFormatter;
@@ -45,20 +46,36 @@ public class DefaultHttpRequestWriterFactory implements HttpMessageWriterFactory
public static final DefaultHttpRequestWriterFactory INSTANCE = new DefaultHttpRequestWriterFactory();
+ private final Http1Config http1Config;
private final LineFormatter lineFormatter;
- public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestWriterFactory(final Http1Config http1Config, final LineFormatter lineFormatter) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
}
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestWriterFactory(final Http1Config http1Config) {
+ this(http1Config, null);
+ }
+
+ public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+ this(null, lineFormatter);
+ }
+
public DefaultHttpRequestWriterFactory() {
- this(null);
+ this(null, null);
}
@Override
public HttpMessageWriter<ClassicHttpRequest> create() {
- return new DefaultHttpRequestWriter(this.lineFormatter);
+ return new DefaultHttpRequestWriter(http1Config, lineFormatter);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParser.java
index c2c4352f5..32d7810c0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParser.java
@@ -48,30 +48,32 @@ public class DefaultHttpResponseParser extends AbstractMessageParser<ClassicHttp
private final HttpResponseFactory<ClassicHttpResponse> responseFactory;
/**
- * Creates new instance of DefaultHttpResponseParser.
- *
- * @param lineParser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used
- * @param responseFactory the response factory. If {@code null}
- * {@link DefaultClassicHttpResponseFactory#INSTANCE} will be used.
- * @param http1Config the message http1Config. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
*/
+ public DefaultHttpResponseParser(
+ final Http1Config http1Config,
+ final LineParser lineParser,
+ final HttpResponseFactory<ClassicHttpResponse> responseFactory) {
+ super(http1Config, lineParser);
+ this.responseFactory = responseFactory != null ? responseFactory : DefaultClassicHttpResponseFactory.INSTANCE;
+ }
+
+ /**
+ * @deprecated Use {@link #DefaultHttpResponseParser(Http1Config, LineParser, HttpResponseFactory)}
+ */
+ @Deprecated
public DefaultHttpResponseParser(
final LineParser lineParser,
final HttpResponseFactory<ClassicHttpResponse> responseFactory,
final Http1Config http1Config) {
- super(lineParser, http1Config);
- this.responseFactory = responseFactory != null ? responseFactory : DefaultClassicHttpResponseFactory.INSTANCE;
+ this(http1Config, lineParser, responseFactory);
}
/**
* @since 4.3
*/
public DefaultHttpResponseParser(final Http1Config http1Config) {
- this(null, null, http1Config);
+ this(http1Config, null, null);
}
/**
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParserFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParserFactory.java
index 9e602f789..59422fb7b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParserFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseParserFactory.java
@@ -47,23 +47,51 @@ public class DefaultHttpResponseParserFactory implements HttpMessageParserFactor
public static final DefaultHttpResponseParserFactory INSTANCE = new DefaultHttpResponseParserFactory();
+ private final Http1Config http1Config;
private final LineParser lineParser;
private final HttpResponseFactory<ClassicHttpResponse> responseFactory;
- public DefaultHttpResponseParserFactory(final LineParser lineParser,
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseParserFactory(
+ final Http1Config http1Config,
+ final LineParser lineParser,
final HttpResponseFactory<ClassicHttpResponse> responseFactory) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineParser = lineParser != null ? lineParser : LazyLaxLineParser.INSTANCE;
this.responseFactory = responseFactory != null ? responseFactory : DefaultClassicHttpResponseFactory.INSTANCE;
}
+ public DefaultHttpResponseParserFactory(final LineParser lineParser,
+ final HttpResponseFactory<ClassicHttpResponse> responseFactory) {
+ this(null, lineParser, responseFactory);
+ }
+
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseParserFactory(final Http1Config http1Config) {
+ this(http1Config, null, null);
+ }
+
public DefaultHttpResponseParserFactory() {
this(null, null);
}
+ /**
+ * @deprecated Use {@link #create()}
+ */
+ @Deprecated
@Override
public HttpMessageParser<ClassicHttpResponse> create(final Http1Config http1Config) {
- return new DefaultHttpResponseParser(this.lineParser, this.responseFactory, http1Config);
+ return new DefaultHttpResponseParser(http1Config, this.lineParser, this.responseFactory);
+ }
+
+ @Override
+ public HttpMessageParser<ClassicHttpResponse> create() {
+ return new DefaultHttpResponseParser(this.http1Config, this.lineParser, this.responseFactory);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriter.java
index 478a4aa48..8f5667104 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriter.java
@@ -30,8 +30,9 @@ package org.apache.hc.core5.http.impl.io;
import java.io.IOException;
import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.util.CharArrayBuffer;
@@ -44,27 +45,39 @@ import org.apache.hc.core5.util.CharArrayBuffer;
*/
public class DefaultHttpResponseWriter extends AbstractMessageWriter<ClassicHttpResponse> {
+ private final Http1Config http1Config;
+
/**
- * Creates an instance of DefaultHttpResponseWriter.
- *
- * @param formatter the line formatter If {@code null}
- * {@link org.apache.hc.core5.http.message.BasicLineFormatter#INSTANCE}
- * will be used.
+ * @since 5.3
*/
- public DefaultHttpResponseWriter(final LineFormatter formatter) {
+ public DefaultHttpResponseWriter(final Http1Config http1Config, final LineFormatter formatter) {
super(formatter);
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
+ }
+
+ public DefaultHttpResponseWriter(final LineFormatter formatter) {
+ this(null, formatter);
}
public DefaultHttpResponseWriter() {
- super(null);
+ this(null, null);
+ }
+
+ /**
+ * Determines the HTTP protocol version to be communicated to the opposite
+ * endpoint in the message header.
+ *
+ * @since 5.3
+ */
+ protected HttpVersion protocolVersion(final HttpResponse message) {
+ return http1Config.getVersion();
}
@Override
protected void writeHeadLine(
final ClassicHttpResponse message, final CharArrayBuffer lineBuf) throws IOException {
- final ProtocolVersion transportVersion = message.getVersion();
getLineFormatter().formatStatusLine(lineBuf, new StatusLine(
- transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1,
+ protocolVersion(message),
message.getCode(),
message.getReasonPhrase()));
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriterFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriterFactory.java
index beac2f565..75ae97a16 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriterFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultHttpResponseWriterFactory.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.http.impl.io;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.io.HttpMessageWriter;
import org.apache.hc.core5.http.io.HttpMessageWriterFactory;
import org.apache.hc.core5.http.message.BasicLineFormatter;
@@ -45,20 +46,36 @@ public class DefaultHttpResponseWriterFactory implements HttpMessageWriterFactor
public static final DefaultHttpResponseWriterFactory INSTANCE = new DefaultHttpResponseWriterFactory();
+ private final Http1Config http1Config;
private final LineFormatter lineFormatter;
- public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseWriterFactory(final Http1Config http1Config, final LineFormatter lineFormatter) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
}
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseWriterFactory(final Http1Config http1Config) {
+ this(http1Config, null);
+ }
+
+ public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+ this(null, lineFormatter);
+ }
+
public DefaultHttpResponseWriterFactory() {
- this(null);
+ this(null, null);
}
@Override
public HttpMessageWriter<ClassicHttpResponse> create() {
- return new DefaultHttpResponseWriter(this.lineFormatter);
+ return new DefaultHttpResponseWriter(http1Config, lineFormatter);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
index 7f6ad6796..ed52cebba 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpRequestExecutor.java
@@ -44,6 +44,7 @@ import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.io.HttpClientConnection;
@@ -75,31 +76,46 @@ public class HttpRequestExecutor {
public static final Timeout DEFAULT_WAIT_FOR_CONTINUE = Timeout.ofSeconds(3);
- private final Timeout waitForContinue;
+ private final Http1Config http1Config;
private final ConnectionReuseStrategy connReuseStrategy;
private final Http1StreamListener streamListener;
/**
* Creates new instance of HttpRequestExecutor.
*
- * @since 4.3
+ * @since 5.3
*/
public HttpRequestExecutor(
- final Timeout waitForContinue,
+ final Http1Config http1Config,
final ConnectionReuseStrategy connReuseStrategy,
final Http1StreamListener streamListener) {
super();
- this.waitForContinue = Args.positive(waitForContinue, "Wait for continue time");
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.connReuseStrategy = connReuseStrategy != null ? connReuseStrategy : DefaultConnectionReuseStrategy.INSTANCE;
this.streamListener = streamListener;
}
+ /**
+ * @deprecated Use {@link #HttpRequestExecutor(Http1Config, ConnectionReuseStrategy, Http1StreamListener)}
+ */
+ @Deprecated
+ public HttpRequestExecutor(
+ final Timeout waitForContinue,
+ final ConnectionReuseStrategy connReuseStrategy,
+ final Http1StreamListener streamListener) {
+ this(Http1Config.custom()
+ .setWaitForContinueTimeout(waitForContinue)
+ .build(),
+ connReuseStrategy,
+ streamListener);
+ }
+
public HttpRequestExecutor(final ConnectionReuseStrategy connReuseStrategy) {
- this(DEFAULT_WAIT_FOR_CONTINUE, connReuseStrategy, null);
+ this(Http1Config.DEFAULT, connReuseStrategy, null);
}
public HttpRequestExecutor() {
- this(DEFAULT_WAIT_FOR_CONTINUE, null, null);
+ this(Http1Config.DEFAULT, null, null);
}
/**
@@ -145,7 +161,8 @@ public class HttpRequestExecutor {
ClassicHttpResponse response = null;
while (response == null) {
if (expectContinue) {
- if (conn.isDataAvailable(this.waitForContinue)) {
+ final Timeout timeout = http1Config.getWaitForContinueTimeout() != null ? http1Config.getWaitForContinueTimeout() : DEFAULT_WAIT_FOR_CONTINUE;
+ if (conn.isDataAvailable(timeout)) {
response = conn.receiveResponseHeader();
if (streamListener != null) {
streamListener.onResponseHead(conn, response);
@@ -238,10 +255,10 @@ public class HttpRequestExecutor {
Args.notNull(processor, "HTTP processor");
Args.notNull(context, "HTTP context");
final ProtocolVersion transportVersion = request.getVersion();
- if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
+ if (transportVersion != null && !transportVersion.lessEquals(http1Config.getVersion())) {
throw new UnsupportedHttpVersionException(transportVersion);
}
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
+ context.setProtocolVersion(transportVersion != null ? transportVersion : http1Config.getVersion());
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
processor.process(request, request.getEntity(), context);
}
@@ -271,7 +288,12 @@ public class HttpRequestExecutor {
Args.notNull(processor, "HTTP processor");
Args.notNull(context, "HTTP context");
final ProtocolVersion transportVersion = response.getVersion();
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
+ if (transportVersion != null) {
+ if (transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
+ throw new UnsupportedHttpVersionException(transportVersion);
+ }
+ context.setProtocolVersion(transportVersion);
+ }
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
processor.process(response, response.getEntity(), context);
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
index 7ae6c0cca..6d0bb8f43 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
@@ -45,6 +45,7 @@ import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.impl.ServerSupport;
@@ -82,13 +83,13 @@ import org.apache.hc.core5.util.Args;
public class HttpService {
private final HttpProcessor processor;
+ private final Http1Config http1Config;
private final HttpServerRequestHandler requestHandler;
private final ConnectionReuseStrategy connReuseStrategy;
private final Http1StreamListener streamListener;
/**
* Create a new HTTP service.
- *
* @param processor the processor to use on requests and responses
* @param handlerMapper the handler mapper
* @param responseFactory the response factory. If {@code null}
@@ -105,6 +106,7 @@ public class HttpService {
final Http1StreamListener streamListener) {
this(processor,
new BasicHttpServerExpectationDecorator(new BasicHttpServerRequestHandler(handlerMapper, responseFactory)),
+ Http1Config.DEFAULT,
connReuseStrategy,
streamListener);
}
@@ -141,9 +143,31 @@ public class HttpService {
final HttpServerRequestHandler requestHandler,
final ConnectionReuseStrategy connReuseStrategy,
final Http1StreamListener streamListener) {
+ this(processor, requestHandler, Http1Config.DEFAULT, connReuseStrategy, streamListener);
+ }
+
+ /**
+ * Create a new HTTP service.
+ *
+ * @param processor the processor to use on requests and responses
+ * @param requestHandler the request handler.
+ * @param http1Config HTTP/1 protocol configuration.
+ * @param connReuseStrategy the connection reuse strategy. If {@code null}
+ * {@link DefaultConnectionReuseStrategy#INSTANCE} will be used.
+ * @param streamListener message stream listener.
+ *
+ * @since 5.3
+ */
+ public HttpService(
+ final HttpProcessor processor,
+ final HttpServerRequestHandler requestHandler,
+ final Http1Config http1Config,
+ final ConnectionReuseStrategy connReuseStrategy,
+ final Http1StreamListener streamListener) {
super();
this.processor = Args.notNull(processor, "HTTP processor");
this.requestHandler = Args.notNull(requestHandler, "Request handler");
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.connReuseStrategy = connReuseStrategy != null ? connReuseStrategy : DefaultConnectionReuseStrategy.INSTANCE;
this.streamListener = streamListener;
}
@@ -156,7 +180,7 @@ public class HttpService {
*/
public HttpService(
final HttpProcessor processor, final HttpServerRequestHandler requestHandler) {
- this(processor, requestHandler, null, null);
+ this(processor, requestHandler, Http1Config.DEFAULT, null, null);
}
/**
@@ -185,7 +209,10 @@ public class HttpService {
}
conn.receiveRequestEntity(request);
final ProtocolVersion transportVersion = request.getVersion();
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
+ if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
+ throw new UnsupportedHttpVersionException(transportVersion);
+ }
+ context.setProtocolVersion(transportVersion != null ? transportVersion : http1Config.getVersion());
context.setAttribute(HttpCoreContext.SSL_SESSION, conn.getSSLSession());
context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, conn.getEndpointDetails());
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
@@ -212,10 +239,12 @@ public class HttpService {
public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
try {
final ProtocolVersion transportVersion = response.getVersion();
- if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
- throw new UnsupportedHttpVersionException(transportVersion);
+ if (transportVersion != null) {
+ if (!transportVersion.lessEquals(http1Config.getVersion())) {
+ throw new UnsupportedHttpVersionException(transportVersion);
+ }
+ context.setProtocolVersion(transportVersion);
}
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
processor.process(response, response.getEntity(), context);
@@ -300,6 +329,7 @@ public class HttpService {
private HttpProcessor processor;
private HttpServerRequestHandler requestHandler;
+ private Http1Config http1Config;
private ConnectionReuseStrategy connReuseStrategy;
private Http1StreamListener streamListener;
@@ -315,6 +345,11 @@ public class HttpService {
return this;
}
+ public Builder withHttp1Config(final Http1Config http1Config) {
+ this.http1Config = http1Config;
+ return this;
+ }
+
public Builder withConnectionReuseStrategy(final ConnectionReuseStrategy connReuseStrategy) {
this.connReuseStrategy = connReuseStrategy;
return this;
@@ -324,6 +359,7 @@ public class HttpService {
this.streamListener = streamListener;
return this;
}
+
/**
* Create a new HTTP service.
*
@@ -333,6 +369,7 @@ public class HttpService {
return new HttpService(
processor,
requestHandler,
+ http1Config,
connReuseStrategy,
streamListener);
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractMessageParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractMessageParser.java
index 9c6dc65fa..17fe3a296 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractMessageParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractMessageParser.java
@@ -37,8 +37,8 @@ import org.apache.hc.core5.http.MessageConstraintException;
import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.LazyLineParser;
import org.apache.hc.core5.http.message.LineParser;
-import org.apache.hc.core5.http.nio.SessionInputBuffer;
import org.apache.hc.core5.http.nio.NHttpMessageParser;
+import org.apache.hc.core5.http.nio.SessionInputBuffer;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.CharArrayBuffer;
@@ -54,6 +54,9 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
READ_HEAD_LINE, READ_HEADERS, COMPLETED
}
+ private final Http1Config http1Config;
+ private final LineParser lineParser;
+
private State state;
private T message;
@@ -61,27 +64,25 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
private final List<CharArrayBuffer> headerBufs;
private int emptyLineCount;
- private final LineParser lineParser;
- private final Http1Config messageConstraints;
-
/**
- * Creates an instance of AbstractMessageParser.
- *
- * @param lineParser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used.
- * @param messageConstraints Message constraints. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
*/
- public AbstractMessageParser(final LineParser lineParser, final Http1Config messageConstraints) {
+ public AbstractMessageParser(final Http1Config http1Config, final LineParser lineParser) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineParser = lineParser != null ? lineParser : LazyLineParser.INSTANCE;
- this.messageConstraints = messageConstraints != null ? messageConstraints : Http1Config.DEFAULT;
this.headerBufs = new ArrayList<>();
this.state = State.READ_HEAD_LINE;
}
+ /**
+ * @deprecated Use {@link #AbstractMessageParser(Http1Config, LineParser)}
+ */
+ @Deprecated
+ public AbstractMessageParser(final LineParser lineParser, final Http1Config messageConstraints) {
+ this(messageConstraints, lineParser);
+ }
+
LineParser getLineParser() {
return this.lineParser;
}
@@ -107,7 +108,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
private T parseHeadLine() throws IOException, HttpException {
if (this.lineBuf.isEmpty()) {
this.emptyLineCount++;
- if (this.emptyLineCount >= this.messageConstraints.getMaxEmptyLineCount()) {
+ if (this.emptyLineCount >= this.http1Config.getMaxEmptyLineCount()) {
throw new MessageConstraintException("Maximum empty line limit exceeded");
}
return null;
@@ -129,7 +130,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
}
i++;
}
- final int maxLineLen = this.messageConstraints.getMaxLineLength();
+ final int maxLineLen = this.http1Config.getMaxLineLength();
if (maxLineLen > 0 && previous.length() + 1 + current.length() - i > maxLineLen) {
throw new MessageConstraintException("Maximum line length limit exceeded");
}
@@ -152,7 +153,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
this.lineBuf.clear();
}
final boolean lineComplete = sessionBuffer.readLine(this.lineBuf, endOfStream);
- final int maxLineLen = this.messageConstraints.getMaxLineLength();
+ final int maxLineLen = this.http1Config.getMaxLineLength();
if (maxLineLen > 0 &&
(this.lineBuf.length() > maxLineLen ||
(!lineComplete && sessionBuffer.length() > maxLineLen))) {
@@ -171,7 +172,7 @@ public abstract class AbstractMessageParser<T extends HttpMessage> implements NH
break;
case READ_HEADERS:
if (this.lineBuf.length() > 0) {
- final int maxHeaderCount = this.messageConstraints.getMaxHeaderCount();
+ final int maxHeaderCount = this.http1Config.getMaxHeaderCount();
if (maxHeaderCount > 0 && headerBufs.size() >= maxHeaderCount) {
throw new MessageConstraintException("Maximum header count exceeded");
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexerFactory.java
index 12544e8bc..54691487e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexerFactory.java
@@ -80,9 +80,9 @@ public final class ClientHttp1StreamDuplexerFactory {
this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
DefaultConnectionReuseStrategy.INSTANCE;
this.responseParserFactory = responseParserFactory != null ? responseParserFactory :
- new DefaultHttpResponseParserFactory(http1Config);
+ new DefaultHttpResponseParserFactory(this.http1Config);
this.requestWriterFactory = requestWriterFactory != null ? requestWriterFactory :
- DefaultHttpRequestWriterFactory.INSTANCE;
+ new DefaultHttpRequestWriterFactory(this.http1Config);
this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
DefaultContentLengthStrategy.INSTANCE;
this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index 244a696e9..11fc5b9be 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -56,6 +56,8 @@ import org.apache.hc.core5.util.Timeout;
class ClientHttp1StreamHandler implements ResourceHolder {
+ public static final Timeout DEFAULT_WAIT_FOR_CONTINUE = Timeout.ofSeconds(3);
+
private final Http1StreamChannel<HttpRequest> outputChannel;
private final DataStreamChannel internalDataChannel;
private final HttpProcessor httpProcessor;
@@ -144,10 +146,10 @@ class ClientHttp1StreamHandler implements ResourceHolder {
private void commitRequest(final HttpRequest request, final EntityDetails entityDetails) throws IOException, HttpException {
if (requestCommitted.compareAndSet(false, true)) {
final ProtocolVersion transportVersion = request.getVersion();
- if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
+ if (transportVersion != null && !transportVersion.lessEquals(http1Config.getVersion())) {
throw new UnsupportedHttpVersionException(transportVersion);
}
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
+ context.setProtocolVersion(transportVersion != null ? transportVersion : http1Config.getVersion());
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
httpProcessor.process(request, entityDetails, context);
@@ -165,7 +167,8 @@ class ClientHttp1StreamHandler implements ResourceHolder {
if (expectContinue) {
requestState = MessageState.ACK;
timeout = outputChannel.getSocketTimeout();
- outputChannel.setSocketTimeout(http1Config.getWaitForContinueTimeout());
+ final Timeout timeout = http1Config.getWaitForContinueTimeout() != null ? http1Config.getWaitForContinueTimeout() : DEFAULT_WAIT_FOR_CONTINUE;
+ outputChannel.setSocketTimeout(timeout);
} else {
requestState = MessageState.BODY;
exchangeHandler.produce(internalDataChannel);
@@ -196,8 +199,11 @@ class ClientHttp1StreamHandler implements ResourceHolder {
throw new ProtocolException("Unexpected message head");
}
final ProtocolVersion transportVersion = response.getVersion();
- if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
- throw new UnsupportedHttpVersionException(transportVersion);
+ if (transportVersion != null) {
+ if (transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
+ throw new UnsupportedHttpVersionException(transportVersion);
+ }
+ context.setProtocolVersion(transportVersion);
}
final int status = response.getCode();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParser.java
index 67724df13..67f5cffc8 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParser.java
@@ -51,36 +51,47 @@ public class DefaultHttpRequestParser<T extends HttpRequest> extends AbstractMes
private final HttpRequestFactory<T> requestFactory;
/**
- * Creates an instance of DefaultHttpRequestParser.
- *
- * @param requestFactory the request factory.
- * @param parser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used.
- * @param http1Config Message http1Config. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
*/
public DefaultHttpRequestParser(
- final HttpRequestFactory<T> requestFactory,
+ final Http1Config http1Config,
final LineParser parser,
- final Http1Config http1Config) {
- super(parser, http1Config);
+ final HttpRequestFactory<T> requestFactory) {
+ super(http1Config, parser);
this.requestFactory = Args.notNull(requestFactory, "Request factory");
}
/**
- * @since 4.3
- */
+ * @since 5.3
+ */
+ public DefaultHttpRequestParser(final Http1Config http1Config, final HttpRequestFactory<T> requestFactory) {
+ this(http1Config, null, requestFactory);
+ }
+
+ /**
+ * @deprecated Use {@link #DefaultHttpRequestParser(Http1Config, HttpRequestFactory)} }
+ */
+ @Deprecated
public DefaultHttpRequestParser(final HttpRequestFactory<T> requestFactory, final Http1Config http1Config) {
this(requestFactory, null, http1Config);
}
/**
- * @since 4.3
- */
+ * @deprecated Use {@link #DefaultHttpRequestParser(Http1Config, LineParser, HttpRequestFactory)} }
+ */
+ @Deprecated
+ public DefaultHttpRequestParser(
+ final HttpRequestFactory<T> requestFactory,
+ final LineParser parser,
+ final Http1Config http1Config) {
+ this(http1Config, parser, requestFactory);
+ }
+
+ /**
+ * @since 4.3
+ */
public DefaultHttpRequestParser(final HttpRequestFactory<T> requestFactory) {
- this(requestFactory, null);
+ this(null, null, requestFactory);
}
@Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParserFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParserFactory.java
index e0db9ab3b..d3ba90f81 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParserFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestParserFactory.java
@@ -71,7 +71,7 @@ public class DefaultHttpRequestParserFactory implements NHttpMessageParserFactor
@Override
public NHttpMessageParser<HttpRequest> create() {
- return new DefaultHttpRequestParser<>(requestFactory, lineParser, http1Config);
+ return new DefaultHttpRequestParser<>(http1Config, lineParser, requestFactory);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriter.java
index 480d4a32e..b79a02ae1 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriter.java
@@ -31,7 +31,7 @@ import java.io.IOException;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.message.RequestLine;
import org.apache.hc.core5.util.CharArrayBuffer;
@@ -43,6 +43,16 @@ import org.apache.hc.core5.util.CharArrayBuffer;
*/
public class DefaultHttpRequestWriter<T extends HttpRequest> extends AbstractMessageWriter<T> {
+ private final Http1Config http1Config;
+
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestWriter(final Http1Config http1Config, final LineFormatter formatter) {
+ super(formatter);
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
+ }
+
/**
* Creates an instance of DefaultHttpRequestWriter.
*
@@ -52,24 +62,33 @@ public class DefaultHttpRequestWriter<T extends HttpRequest> extends AbstractMes
* @since 4.3
*/
public DefaultHttpRequestWriter(final LineFormatter formatter) {
- super(formatter);
+ this(null, formatter);
}
/**
* @since 4.3
*/
public DefaultHttpRequestWriter() {
- super(null);
+ this(null, null);
+ }
+
+ /**
+ * Determines the HTTP protocol version to be communicated to the opposite
+ * endpoint in the message header.
+ *
+ * @since 5.3
+ */
+ protected HttpVersion protocolVersion(final T request) {
+ return http1Config.getVersion();
}
@Override
protected void writeHeadLine(final T message, final CharArrayBuffer lineBuf) throws IOException {
lineBuf.clear();
- final ProtocolVersion transportVersion = message.getVersion();
getLineFormatter().formatRequestLine(lineBuf, new RequestLine(
message.getMethod(),
message.getRequestUri(),
- transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1));
+ protocolVersion(message)));
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriterFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriterFactory.java
index 013b16adf..c71a557b0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriterFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpRequestWriterFactory.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.http.impl.nio;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.BasicLineFormatter;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.nio.NHttpMessageWriter;
@@ -45,20 +46,36 @@ public class DefaultHttpRequestWriterFactory implements NHttpMessageWriterFactor
public static final DefaultHttpRequestWriterFactory INSTANCE = new DefaultHttpRequestWriterFactory();
+ private final Http1Config http1Config;
private final LineFormatter lineFormatter;
- public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestWriterFactory(final Http1Config http1Config, final LineFormatter lineFormatter) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
}
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpRequestWriterFactory(final Http1Config http1Config) {
+ this(http1Config, null);
+ }
+
+ public DefaultHttpRequestWriterFactory(final LineFormatter lineFormatter) {
+ this(null, lineFormatter);
+ }
+
public DefaultHttpRequestWriterFactory() {
- this(null);
+ this(null, null);
}
@Override
public NHttpMessageWriter<HttpRequest> create() {
- return new DefaultHttpRequestWriter<>(this.lineFormatter);
+ return new DefaultHttpRequestWriter<>(http1Config, lineFormatter);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParser.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParser.java
index ec05fad04..66a7b3528 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParser.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParser.java
@@ -46,27 +46,40 @@ public class DefaultHttpResponseParser<T extends HttpResponse> extends AbstractM
private final HttpResponseFactory<T> responseFactory;
/**
- * Creates an instance of DefaultHttpResponseParser.
- *
- * @param responseFactory the response factory.
- * @param parser the line parser. If {@code null}
- * {@link org.apache.hc.core5.http.message.LazyLineParser#INSTANCE} will be used.
- * @param http1Config Message http1Config. If {@code null}
- * {@link Http1Config#DEFAULT} will be used.
- *
- * @since 4.3
+ * @since 5.3
+ */
+ public DefaultHttpResponseParser(
+ final Http1Config http1Config,
+ final LineParser parser,
+ final HttpResponseFactory<T> responseFactory) {
+ super(http1Config, parser);
+ this.responseFactory = Args.notNull(responseFactory, "Response factory");
+ }
+
+ /**
+ * @since 5.3
*/
+ public DefaultHttpResponseParser(
+ final Http1Config http1Config,
+ final HttpResponseFactory<T> responseFactory) {
+ this(http1Config, null, responseFactory);
+ }
+
+ /**
+ * @deprecated Use {@link #DefaultHttpResponseParser(Http1Config, LineParser, HttpResponseFactory)}
+ */
+ @Deprecated
public DefaultHttpResponseParser(
final HttpResponseFactory<T> responseFactory,
final LineParser parser,
final Http1Config http1Config) {
- super(parser, http1Config);
- this.responseFactory = Args.notNull(responseFactory, "Response factory");
+ this(http1Config, parser, responseFactory);
}
/**
- * @since 4.3
+ * @deprecated Use {@link #DefaultHttpResponseParser(Http1Config, HttpResponseFactory)}
*/
+ @Deprecated
public DefaultHttpResponseParser(final HttpResponseFactory<T> responseFactory, final Http1Config http1Config) {
this(responseFactory, null, http1Config);
}
@@ -75,7 +88,7 @@ public class DefaultHttpResponseParser<T extends HttpResponse> extends AbstractM
* @since 4.3
*/
public DefaultHttpResponseParser(final HttpResponseFactory<T> responseFactory) {
- this(responseFactory, null);
+ this(null, null, responseFactory);
}
@Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParserFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParserFactory.java
index a6c8b3d31..01fcb03ef 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParserFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseParserFactory.java
@@ -71,7 +71,7 @@ public class DefaultHttpResponseParserFactory implements NHttpMessageParserFacto
@Override
public NHttpMessageParser<HttpResponse> create() {
- return new DefaultHttpResponseParser<>(responseFactory, lineParser, http1Config);
+ return new DefaultHttpResponseParser<>(http1Config, lineParser, responseFactory);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriter.java
index ea9922bca..80e3359ef 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriter.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriter.java
@@ -31,7 +31,7 @@ import java.io.IOException;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.ProtocolVersion;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.util.CharArrayBuffer;
@@ -43,6 +43,16 @@ import org.apache.hc.core5.util.CharArrayBuffer;
*/
public class DefaultHttpResponseWriter<T extends HttpResponse> extends AbstractMessageWriter<T> {
+ private final Http1Config http1Config;
+
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseWriter(final LineFormatter formatter, final Http1Config http1Config) {
+ super(formatter);
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
+ }
+
/**
* Creates an instance of DefaultHttpResponseWriter.
*
@@ -52,22 +62,31 @@ public class DefaultHttpResponseWriter<T extends HttpResponse> extends AbstractM
* @since 4.3
*/
public DefaultHttpResponseWriter(final LineFormatter formatter) {
- super(formatter);
+ this(formatter, null);
}
/**
* @since 4.3
*/
public DefaultHttpResponseWriter() {
- super(null);
+ this(null, null);
+ }
+
+ /**
+ * Determines the HTTP protocol version to be communicated to the opposite
+ * endpoint in the message header.
+ *
+ * @since 5.3
+ */
+ protected HttpVersion protocolVersion(final T request) {
+ return http1Config.getVersion();
}
@Override
protected void writeHeadLine(final T message, final CharArrayBuffer lineBuf) throws IOException {
lineBuf.clear();
- final ProtocolVersion transportVersion = message.getVersion();
getLineFormatter().formatStatusLine(lineBuf, new StatusLine(
- transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1,
+ protocolVersion(message),
message.getCode(),
message.getReasonPhrase()));
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriterFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriterFactory.java
index 6c08c655f..9cd5d63f4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriterFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/DefaultHttpResponseWriterFactory.java
@@ -30,6 +30,7 @@ package org.apache.hc.core5.http.impl.nio;
import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.message.BasicLineFormatter;
import org.apache.hc.core5.http.message.LineFormatter;
import org.apache.hc.core5.http.nio.NHttpMessageWriter;
@@ -45,20 +46,36 @@ public class DefaultHttpResponseWriterFactory implements NHttpMessageWriterFacto
public static final DefaultHttpResponseWriterFactory INSTANCE = new DefaultHttpResponseWriterFactory();
+ private final Http1Config http1Config;
private final LineFormatter lineFormatter;
- public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseWriterFactory(final Http1Config http1Config, final LineFormatter lineFormatter) {
super();
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.lineFormatter = lineFormatter != null ? lineFormatter : BasicLineFormatter.INSTANCE;
}
+ /**
+ * @since 5.3
+ */
+ public DefaultHttpResponseWriterFactory(final Http1Config http1Config) {
+ this(http1Config, null);
+ }
+
+ public DefaultHttpResponseWriterFactory(final LineFormatter lineFormatter) {
+ this(null, lineFormatter);
+ }
+
public DefaultHttpResponseWriterFactory() {
- this(null);
+ this(null, null);
}
@Override
public NHttpMessageWriter<HttpResponse> create() {
- return new DefaultHttpResponseWriter<>(this.lineFormatter);
+ return new DefaultHttpResponseWriter<>(lineFormatter, http1Config);
}
}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
index 4a886d7d5..43f4f7fb7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
@@ -320,6 +320,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
streamHandler = new ServerHttp1StreamHandler(
outputChannel,
httpProcessor,
+ http1Config,
connectionReuseStrategy,
exchangeHandlerFactory,
context);
@@ -328,6 +329,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
streamHandler = new ServerHttp1StreamHandler(
new DelayedOutputChannel(outputChannel),
httpProcessor,
+ http1Config,
connectionReuseStrategy,
exchangeHandlerFactory,
context);
@@ -350,6 +352,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
streamHandler = new ServerHttp1StreamHandler(
outputChannel,
httpProcessor,
+ http1Config,
connectionReuseStrategy,
exchangeHandlerFactory,
context);
@@ -358,6 +361,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
streamHandler = new ServerHttp1StreamHandler(
new DelayedOutputChannel(outputChannel),
httpProcessor,
+ http1Config,
connectionReuseStrategy,
exchangeHandlerFactory,
context);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexerFactory.java
index 5d1c6464e..7c078b6e7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexerFactory.java
@@ -85,9 +85,9 @@ public final class ServerHttp1StreamDuplexerFactory {
this.connectionReuseStrategy = connectionReuseStrategy != null ? connectionReuseStrategy :
DefaultConnectionReuseStrategy.INSTANCE;
this.requestParserFactory = requestParserFactory != null ? requestParserFactory :
- new DefaultHttpRequestParserFactory(http1Config);
+ new DefaultHttpRequestParserFactory(this.http1Config);
this.responseWriterFactory = responseWriterFactory != null ? responseWriterFactory :
- DefaultHttpResponseWriterFactory.INSTANCE;
+ new DefaultHttpResponseWriterFactory(this.http1Config);
this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :
DefaultContentLengthStrategy.INSTANCE;
this.outgoingContentStrategy = outgoingContentStrategy != null ? outgoingContentStrategy :
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
index 0bc6b0112..721d0ae8b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
@@ -46,6 +46,7 @@ import org.apache.hc.core5.http.MisdirectedRequestException;
import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.UnsupportedHttpVersionException;
+import org.apache.hc.core5.http.config.Http1Config;
import org.apache.hc.core5.http.impl.ServerSupport;
import org.apache.hc.core5.http.message.BasicHttpResponse;
import org.apache.hc.core5.http.nio.AsyncPushProducer;
@@ -68,6 +69,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
private final DataStreamChannel internalDataChannel;
private final ResponseChannel responseChannel;
private final HttpProcessor httpProcessor;
+ private final Http1Config http1Config;
private final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory;
private final ConnectionReuseStrategy connectionReuseStrategy;
private final HttpCoreContext context;
@@ -83,6 +85,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
ServerHttp1StreamHandler(
final Http1StreamChannel<HttpResponse> outputChannel,
final HttpProcessor httpProcessor,
+ final Http1Config http1Config,
final ConnectionReuseStrategy connectionReuseStrategy,
final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory,
final HttpCoreContext context) {
@@ -142,6 +145,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
};
this.httpProcessor = httpProcessor;
+ this.http1Config = http1Config != null ? http1Config : Http1Config.DEFAULT;
this.connectionReuseStrategy = connectionReuseStrategy;
this.exchangeHandlerFactory = exchangeHandlerFactory;
this.context = context;
@@ -158,8 +162,11 @@ class ServerHttp1StreamHandler implements ResourceHolder {
if (responseCommitted.compareAndSet(false, true)) {
final ProtocolVersion transportVersion = response.getVersion();
- if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
- throw new UnsupportedHttpVersionException(transportVersion);
+ if (transportVersion != null) {
+ if (!transportVersion.lessEquals(http1Config.getVersion())) {
+ throw new UnsupportedHttpVersionException(transportVersion);
+ }
+ context.setProtocolVersion(transportVersion);
}
final int status = response.getCode();
@@ -167,7 +174,6 @@ class ServerHttp1StreamHandler implements ResourceHolder {
throw new HttpException("Invalid response: " + status);
}
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response);
httpProcessor.process(response, responseEntityDetails, context);
@@ -262,7 +268,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) {
throw new UnsupportedHttpVersionException(transportVersion);
}
- context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1);
+ context.setProtocolVersion(transportVersion != null ? transportVersion : http1Config.getVersion());
context.setAttribute(HttpCoreContext.HTTP_REQUEST, request);
try {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpMessageParserFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpMessageParserFactory.java
index 9522cea28..676368f49 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpMessageParserFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpMessageParserFactory.java
@@ -37,6 +37,14 @@ import org.apache.hc.core5.http.config.Http1Config;
*/
public interface HttpMessageParserFactory<T extends MessageHeaders> {
+ /**
+ * @deprecated Use {@link #create()}
+ */
+ @Deprecated
HttpMessageParser<T> create(Http1Config http1Config);
+ default HttpMessageParser<T> create() {
+ return create(Http1Config.DEFAULT);
+ }
+
}