From 889992ca1c8cac670f8925e37463469708202e00 Mon Sep 17 00:00:00 2001 From: David Golombek Date: Fri, 23 Jun 2023 14:11:42 -0400 Subject: [PATCH] Add config for allowDuplicateContentLengths Allow users to configure HttpClientCodec's parseHttpAfterConnectRequest and allowDuplicateContentLengths flags. Fixes #1889 --- .../AsyncHttpClientConfig.java | 4 +++ .../DefaultAsyncHttpClientConfig.java | 33 +++++++++++++++++++ .../config/AsyncHttpClientConfigDefaults.java | 10 ++++++ .../netty/channel/ChannelManager.java | 4 ++- .../config/ahc-default.properties | 2 ++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java b/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java index 972fa0b3a..686a38ae0 100644 --- a/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java +++ b/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java @@ -290,6 +290,10 @@ public interface AsyncHttpClientConfig { int getHttpClientCodecInitialBufferSize(); + boolean getHttpClientParseHttpAfterConnectRequest(); + + boolean getHttpClientAllowDuplicateContentLengths(); + boolean isDisableZeroCopy(); int getHandshakeTimeout(); diff --git a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java index 059cc3e78..3a1701547 100644 --- a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java +++ b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java @@ -66,6 +66,8 @@ import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHashedWheelTimerSize; import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHashedWheelTimerTickDuration; import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecInitialBufferSize; +import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientParseHttpAfterConnectRequest; +import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientAllowDuplicateContentLengths; import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxChunkSize; import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxHeaderSize; import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxInitialLineLength; @@ -181,6 +183,8 @@ public class DefaultAsyncHttpClientConfig implements AsyncHttpClientConfig { private final int httpClientCodecMaxHeaderSize; private final int httpClientCodecMaxChunkSize; private final int httpClientCodecInitialBufferSize; + private final boolean httpClientParseHttpAfterConnectRequest; + private final boolean httpClientAllowDuplicateContentLengths; private final int chunkedFileChunkSize; private final Map, Object> channelOptions; private final @Nullable EventLoopGroup eventLoopGroup; @@ -275,6 +279,8 @@ private DefaultAsyncHttpClientConfig(// http int httpClientCodecMaxHeaderSize, int httpClientCodecMaxChunkSize, int httpClientCodecInitialBufferSize, + boolean httpClientParseHttpAfterConnectRequest, + boolean httpClientAllowDuplicateContentLengths, int chunkedFileChunkSize, int webSocketMaxBufferSize, int webSocketMaxFrameSize, @@ -369,6 +375,8 @@ private DefaultAsyncHttpClientConfig(// http this.httpClientCodecMaxHeaderSize = httpClientCodecMaxHeaderSize; this.httpClientCodecMaxChunkSize = httpClientCodecMaxChunkSize; this.httpClientCodecInitialBufferSize = httpClientCodecInitialBufferSize; + this.httpClientParseHttpAfterConnectRequest = httpClientParseHttpAfterConnectRequest; + this.httpClientAllowDuplicateContentLengths = httpClientAllowDuplicateContentLengths; this.chunkedFileChunkSize = chunkedFileChunkSize; this.channelOptions = channelOptions; this.eventLoopGroup = eventLoopGroup; @@ -704,6 +712,17 @@ public int getHttpClientCodecInitialBufferSize() { return httpClientCodecInitialBufferSize; } + @Override + public boolean getHttpClientParseHttpAfterConnectRequest() { + return httpClientParseHttpAfterConnectRequest; + } + + @Override + public boolean getHttpClientAllowDuplicateContentLengths() { + return httpClientAllowDuplicateContentLengths; + } + + @Override public int getChunkedFileChunkSize() { return chunkedFileChunkSize; @@ -857,6 +876,8 @@ public static class Builder { private int httpClientCodecMaxHeaderSize = defaultHttpClientCodecMaxHeaderSize(); private int httpClientCodecMaxChunkSize = defaultHttpClientCodecMaxChunkSize(); private int httpClientCodecInitialBufferSize = defaultHttpClientCodecInitialBufferSize(); + private boolean httpClientParseHttpAfterConnectRequest = defaultHttpClientParseHttpAfterConnectRequest(); + private boolean httpClientAllowDuplicateContentLengths = defaultHttpClientAllowDuplicateContentLengths(); private int chunkedFileChunkSize = defaultChunkedFileChunkSize(); private boolean useNativeTransport = defaultUseNativeTransport(); private boolean useOnlyEpollNativeTransport = defaultUseOnlyEpollNativeTransport(); @@ -1329,6 +1350,16 @@ public Builder setHttpClientCodecInitialBufferSize(int httpClientCodecInitialBuf return this; } + public Builder setHttpClientParseHttpAfterConnectRequest(boolean httpClientParseHttpAfterConnectRequest) { + this.httpClientParseHttpAfterConnectRequest = httpClientParseHttpAfterConnectRequest; + return this; + } + + public Builder setHttpClientAllowDuplicateContentLengths(boolean httpClientAllowDuplicateContentLengths) { + this.httpClientAllowDuplicateContentLengths = httpClientAllowDuplicateContentLengths; + return this; + } + public Builder setChunkedFileChunkSize(int chunkedFileChunkSize) { this.chunkedFileChunkSize = chunkedFileChunkSize; return this; @@ -1477,6 +1508,8 @@ public DefaultAsyncHttpClientConfig build() { httpClientCodecMaxHeaderSize, httpClientCodecMaxChunkSize, httpClientCodecInitialBufferSize, + httpClientParseHttpAfterConnectRequest, + httpClientAllowDuplicateContentLengths, chunkedFileChunkSize, webSocketMaxBufferSize, webSocketMaxFrameSize, diff --git a/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java b/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java index 3d4cb6106..f789ddb76 100644 --- a/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java +++ b/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java @@ -69,6 +69,8 @@ public final class AsyncHttpClientConfigDefaults { public static final String HTTP_CLIENT_CODEC_MAX_HEADER_SIZE_CONFIG = "httpClientCodecMaxHeaderSize"; public static final String HTTP_CLIENT_CODEC_MAX_CHUNK_SIZE_CONFIG = "httpClientCodecMaxChunkSize"; public static final String HTTP_CLIENT_CODEC_INITIAL_BUFFER_SIZE_CONFIG = "httpClientCodecInitialBufferSize"; + public static final String HTTP_CLIENT_CODEC_PARSE_HTTP_AFTER_CONNECT_REQUEST = "httpClientCodecParseHttpAfterConnectRequest"; + public static final String HTTP_CLIENT_CODEC_ALLOW_DUPLICATE_CONTENT_LENGTHS = "httpClientCodecAllowDuplicateContentLengths"; public static final String DISABLE_ZERO_COPY_CONFIG = "disableZeroCopy"; public static final String HANDSHAKE_TIMEOUT_CONFIG = "handshakeTimeout"; public static final String CHUNKED_FILE_CHUNK_SIZE_CONFIG = "chunkedFileChunkSize"; @@ -271,6 +273,14 @@ public static int defaultHttpClientCodecInitialBufferSize() { return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_INITIAL_BUFFER_SIZE_CONFIG); } + public static boolean defaultHttpClientParseHttpAfterConnectRequest() { + return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getBoolean(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_PARSE_HTTP_AFTER_CONNECT_REQUEST); + } + + public static boolean defaultHttpClientAllowDuplicateContentLengths() { + return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getBoolean(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_ALLOW_DUPLICATE_CONTENT_LENGTHS); + } + public static boolean defaultDisableZeroCopy() { return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getBoolean(ASYNC_CLIENT_CONFIG_ROOT + DISABLE_ZERO_COPY_CONFIG); } diff --git a/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java b/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java index 45ff3adc1..1e87595c8 100755 --- a/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java +++ b/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java @@ -366,7 +366,9 @@ private HttpClientCodec newHttpClientCodec() { config.getHttpClientCodecMaxChunkSize(), false, config.isValidateResponseHeaders(), - config.getHttpClientCodecInitialBufferSize()); + config.getHttpClientCodecInitialBufferSize(), + config.getHttpClientParseHttpAfterConnectRequest(), + config.getHttpClientAllowDuplicateContentLengths()); } private SslHandler createSslHandler(String peerHost, int peerPort) { diff --git a/client/src/main/resources/org/asynchttpclient/config/ahc-default.properties b/client/src/main/resources/org/asynchttpclient/config/ahc-default.properties index 6450221b0..73b5c75d3 100644 --- a/client/src/main/resources/org/asynchttpclient/config/ahc-default.properties +++ b/client/src/main/resources/org/asynchttpclient/config/ahc-default.properties @@ -41,6 +41,8 @@ org.asynchttpclient.httpClientCodecMaxInitialLineLength=4096 org.asynchttpclient.httpClientCodecMaxHeaderSize=8192 org.asynchttpclient.httpClientCodecMaxChunkSize=8192 org.asynchttpclient.httpClientCodecInitialBufferSize=128 +org.asynchttpclient.httpClientCodecParseHttpAfterConnectRequest=false +org.asynchttpclient.httpClientCodecAllowDuplicateContentLengths=false org.asynchttpclient.disableZeroCopy=false org.asynchttpclient.handshakeTimeout=10000 org.asynchttpclient.chunkedFileChunkSize=8192