From 889992ca1c8cac670f8925e37463469708202e00 Mon Sep 17 00:00:00 2001
From: David Golombek <dgolombek@mylookout.com>
Date: Fri, 23 Jun 2023 14:11:42 -0400
Subject: [PATCH 1/2] 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<ChannelOption<Object>, 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

From adc118a4184ef3c089b8a5965e0910b636734beb Mon Sep 17 00:00:00 2001
From: David Golombek <dgolombek@mylookout.com>
Date: Fri, 23 Jun 2023 16:15:12 -0400
Subject: [PATCH 2/2] Fix naming of variables to match standards

---
 .../AsyncHttpClientConfig.java                |  4 +-
 .../DefaultAsyncHttpClientConfig.java         | 40 +++++++++----------
 .../config/AsyncHttpClientConfigDefaults.java |  4 +-
 .../netty/channel/ChannelManager.java         |  4 +-
 4 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java b/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java
index 686a38ae0..a4bbc6a89 100644
--- a/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java
+++ b/client/src/main/java/org/asynchttpclient/AsyncHttpClientConfig.java
@@ -290,9 +290,9 @@ public interface AsyncHttpClientConfig {
 
     int getHttpClientCodecInitialBufferSize();
 
-    boolean getHttpClientParseHttpAfterConnectRequest();
+    boolean getHttpClientCodecParseHttpAfterConnectRequest();
 
-    boolean getHttpClientAllowDuplicateContentLengths();
+    boolean getHttpClientCodecAllowDuplicateContentLengths();
 
     boolean isDisableZeroCopy();
 
diff --git a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java
index 3a1701547..751c61771 100644
--- a/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java
+++ b/client/src/main/java/org/asynchttpclient/DefaultAsyncHttpClientConfig.java
@@ -66,8 +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.defaultHttpClientCodecParseHttpAfterConnectRequest;
+import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecAllowDuplicateContentLengths;
 import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxChunkSize;
 import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxHeaderSize;
 import static org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultHttpClientCodecMaxInitialLineLength;
@@ -183,8 +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 boolean httpClientCodecParseHttpAfterConnectRequest;
+    private final boolean httpClientCodecAllowDuplicateContentLengths;
     private final int chunkedFileChunkSize;
     private final Map<ChannelOption<Object>, Object> channelOptions;
     private final @Nullable EventLoopGroup eventLoopGroup;
@@ -279,8 +279,8 @@ private DefaultAsyncHttpClientConfig(// http
                                          int httpClientCodecMaxHeaderSize,
                                          int httpClientCodecMaxChunkSize,
                                          int httpClientCodecInitialBufferSize,
-                                         boolean httpClientParseHttpAfterConnectRequest,
-                                         boolean httpClientAllowDuplicateContentLengths,
+                                         boolean httpClientCodecParseHttpAfterConnectRequest,
+                                         boolean httpClientCodecAllowDuplicateContentLengths,
                                          int chunkedFileChunkSize,
                                          int webSocketMaxBufferSize,
                                          int webSocketMaxFrameSize,
@@ -375,8 +375,8 @@ private DefaultAsyncHttpClientConfig(// http
         this.httpClientCodecMaxHeaderSize = httpClientCodecMaxHeaderSize;
         this.httpClientCodecMaxChunkSize = httpClientCodecMaxChunkSize;
         this.httpClientCodecInitialBufferSize = httpClientCodecInitialBufferSize;
-        this.httpClientParseHttpAfterConnectRequest = httpClientParseHttpAfterConnectRequest;
-        this.httpClientAllowDuplicateContentLengths = httpClientAllowDuplicateContentLengths;
+        this.httpClientCodecParseHttpAfterConnectRequest = httpClientCodecParseHttpAfterConnectRequest;
+        this.httpClientCodecAllowDuplicateContentLengths = httpClientCodecAllowDuplicateContentLengths;
         this.chunkedFileChunkSize = chunkedFileChunkSize;
         this.channelOptions = channelOptions;
         this.eventLoopGroup = eventLoopGroup;
@@ -713,13 +713,13 @@ public int getHttpClientCodecInitialBufferSize() {
     }
 
     @Override
-    public boolean getHttpClientParseHttpAfterConnectRequest() {
-        return httpClientParseHttpAfterConnectRequest;
+    public boolean getHttpClientCodecParseHttpAfterConnectRequest() {
+        return httpClientCodecParseHttpAfterConnectRequest;
     }
 
     @Override
-    public boolean getHttpClientAllowDuplicateContentLengths() {
-        return httpClientAllowDuplicateContentLengths;
+    public boolean getHttpClientCodecAllowDuplicateContentLengths() {
+        return httpClientCodecAllowDuplicateContentLengths;
     }
 
 
@@ -876,8 +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 boolean httpClientCodecParseHttpAfterConnectRequest = defaultHttpClientCodecParseHttpAfterConnectRequest();
+        private boolean httpClientCodecAllowDuplicateContentLengths = defaultHttpClientCodecAllowDuplicateContentLengths();
         private int chunkedFileChunkSize = defaultChunkedFileChunkSize();
         private boolean useNativeTransport = defaultUseNativeTransport();
         private boolean useOnlyEpollNativeTransport = defaultUseOnlyEpollNativeTransport();
@@ -1350,13 +1350,13 @@ public Builder setHttpClientCodecInitialBufferSize(int httpClientCodecInitialBuf
             return this;
         }
 
-        public Builder setHttpClientParseHttpAfterConnectRequest(boolean httpClientParseHttpAfterConnectRequest) {
-            this.httpClientParseHttpAfterConnectRequest = httpClientParseHttpAfterConnectRequest;
+        public Builder setHttpClientCodecParseHttpAfterConnectRequest(boolean httpClientCodecParseHttpAfterConnectRequest) {
+            this.httpClientCodecParseHttpAfterConnectRequest = httpClientCodecParseHttpAfterConnectRequest;
             return this;
         }
 
-        public Builder setHttpClientAllowDuplicateContentLengths(boolean httpClientAllowDuplicateContentLengths) {
-            this.httpClientAllowDuplicateContentLengths = httpClientAllowDuplicateContentLengths;
+        public Builder setHttpClientCodecAllowDuplicateContentLengths(boolean httpClientCodecAllowDuplicateContentLengths) {
+            this.httpClientCodecAllowDuplicateContentLengths = httpClientCodecAllowDuplicateContentLengths;
             return this;
         }
 
@@ -1508,8 +1508,8 @@ public DefaultAsyncHttpClientConfig build() {
                     httpClientCodecMaxHeaderSize,
                     httpClientCodecMaxChunkSize,
                     httpClientCodecInitialBufferSize,
-                    httpClientParseHttpAfterConnectRequest,
-                    httpClientAllowDuplicateContentLengths,
+                    httpClientCodecParseHttpAfterConnectRequest,
+                    httpClientCodecAllowDuplicateContentLengths,
                     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 f789ddb76..a950112da 100644
--- a/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java
+++ b/client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigDefaults.java
@@ -273,11 +273,11 @@ public static int defaultHttpClientCodecInitialBufferSize() {
         return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getInt(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_INITIAL_BUFFER_SIZE_CONFIG);
     }
 
-    public static boolean defaultHttpClientParseHttpAfterConnectRequest() {
+    public static boolean defaultHttpClientCodecParseHttpAfterConnectRequest() {
         return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getBoolean(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_PARSE_HTTP_AFTER_CONNECT_REQUEST);
     }
 
-    public static boolean defaultHttpClientAllowDuplicateContentLengths() {
+    public static boolean defaultHttpClientCodecAllowDuplicateContentLengths() {
         return AsyncHttpClientConfigHelper.getAsyncHttpClientConfig().getBoolean(ASYNC_CLIENT_CONFIG_ROOT + HTTP_CLIENT_CODEC_ALLOW_DUPLICATE_CONTENT_LENGTHS);
     }
 
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 1e87595c8..4f8dcfab9 100755
--- a/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java
+++ b/client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java
@@ -367,8 +367,8 @@ private HttpClientCodec newHttpClientCodec() {
                 false,
                 config.isValidateResponseHeaders(),
                 config.getHttpClientCodecInitialBufferSize(),
-                config.getHttpClientParseHttpAfterConnectRequest(),
-                config.getHttpClientAllowDuplicateContentLengths());
+                config.getHttpClientCodecParseHttpAfterConnectRequest(),
+                config.getHttpClientCodecAllowDuplicateContentLengths());
     }
 
     private SslHandler createSslHandler(String peerHost, int peerPort) {