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 2025/02/12 15:21:00 UTC

(httpcomponents-core) 01/01: Bug fix: Corrected state tracking of pipelined message exchanges by HTTP/1.1 async client protocol handler

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

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

commit bd89b7777f943ba323e8221df67c0d03cd0207b4
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Feb 12 15:14:30 2025 +0100

    Bug fix: Corrected state tracking of pipelined message exchanges by   HTTP/1.1 async client protocol handler
---
 .../hc/core5/testing/nio/Http1IntegrationTest.java | 37 ++++++++++++++++++++++
 .../http/impl/nio/ClientHttp1StreamDuplexer.java   |  4 +--
 2 files changed, 39 insertions(+), 2 deletions(-)

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 7cf0027a6..64001b2ac 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
@@ -59,6 +59,7 @@
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.hc.core5.function.Callback;
+import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.ContentLengthStrategy;
 import org.apache.hc.core5.http.ContentType;
@@ -84,6 +85,8 @@
 import org.apache.hc.core5.http.impl.Http1StreamListener;
 import org.apache.hc.core5.http.impl.HttpProcessors;
 import org.apache.hc.core5.http.impl.nio.AbstractContentEncoder;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestFactory;
+import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestParser;
 import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexer;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
@@ -1918,4 +1921,38 @@ void testHeaderTooLargePost() throws Exception {
         Assertions.assertEquals("Maximum line length limit exceeded", result1.getBody());
     }
 
+    @Test
+    void testInvalidRequestMessage() throws Exception {
+        final Http1Config http1Config = Http1Config.DEFAULT;
+        final Http1TestServer server = resources.server();
+        server.configure(http1Config);
+        server.configure(() -> new DefaultHttpRequestParser<HttpRequest>(http1Config, DefaultHttpRequestFactory.INSTANCE) {
+
+            @Override
+            protected HttpRequest createMessage(final CharArrayBuffer buffer) throws HttpException {
+                throw new RuntimeException("Ka-boom");
+            }
+
+        });
+
+        final Http1TestClient client = resources.client();
+
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
+        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.GET, createRequestURI(serverEndpoint, "/hello"));
+
+        final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
+                new BasicRequestProducer(request, null),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+        final ExecutionException executionException = Assertions.assertThrows(ExecutionException.class, () ->
+                future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
+        Assertions.assertInstanceOf(ConnectionClosedException.class, executionException.getCause());
+    }
+
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
index 7299d7251..a67b9926e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
@@ -288,12 +288,12 @@ protected ContentEncoder createContentEncoder(
 
     @Override
     boolean inputIdle() {
-        return incoming == null;
+        return incoming == null && pipeline.isEmpty();
     }
 
     @Override
     boolean outputIdle() {
-        return outgoing == null && pipeline.isEmpty();
+        return outgoing == null;
     }
 
     @Override