From a424ae3615c0bb91c9b18d2da2f25bec109868a2 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Fri, 15 Dec 2023 12:52:06 +0100 Subject: [PATCH 01/15] - fix HttpClientIdleTimeoutTest to wait for server's idle timeout before checking for leaks - improve HttpClientIdleTimeoutTest by making it upload some content - fix FCGI server leak caused by idle timeout - fix H3 server leak caused by idle timeout Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 20 ++++++++++++-- .../org/eclipse/jetty/http3/HTTP3Stream.java | 2 ++ .../jetty/http3/HTTP3StreamConnection.java | 9 +++++++ .../transport/HttpClientIdleTimeoutTest.java | 26 ++++++++++++++++--- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index b38304c2420c..7d649e09c118 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -168,6 +168,8 @@ public void onOpen() @Override public void onFillable() { + if (LOG.isDebugEnabled()) + LOG.debug(">>onFillable enter {} {} {}", this, stream, networkBuffer); acquireInputBuffer(); try { @@ -203,6 +205,11 @@ else if (read == 0) releaseInputBuffer(); // TODO: fail and close ? } + finally + { + if (LOG.isDebugEnabled()) + LOG.debug("< serverIdleTimeoutLatch.countDown()); return true; } }); + connector.setIdleTimeout(serverIdleTimeout); client.setIdleTimeout(idleTimeout); CountDownLatch latch = new CountDownLatch(1); client.newRequest(newURI(transport)) .path("/timeout") + .body(new StringRequestContent("some data")) .send(result -> { if (result.isFailed()) @@ -65,15 +70,20 @@ public boolean handle(Request request, Response response, Callback callback) thr // Verify that after the timeout we can make another request. ContentResponse response = client.newRequest(newURI(transport)) .timeout(5, TimeUnit.SECONDS) + .body(new StringRequestContent("more data")) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Wait for the server's idle timeout to trigger to give it a chance to clean up its resources. + assertTrue(serverIdleTimeoutLatch.await(2 * serverIdleTimeout, TimeUnit.MILLISECONDS)); } @ParameterizedTest @MethodSource("transports") - @Tag("DisableLeakTracking:server:FCGI") public void testRequestIdleTimeout(Transport transport) throws Exception { + long serverIdleTimeout = idleTimeout * 3; + CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { @Override @@ -82,13 +92,17 @@ public boolean handle(Request request, Response response, Callback callback) thr // Do not succeed the callback if it's a timeout request. if (!Request.getPathInContext(request).equals("/timeout")) callback.succeeded(); + else + request.addFailureListener(x -> serverIdleTimeoutLatch.countDown()); return true; } }); + connector.setIdleTimeout(serverIdleTimeout); CountDownLatch latch = new CountDownLatch(1); client.newRequest(newURI(transport)) .path("/timeout") + .body(new StringRequestContent("some data")) .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS) .send(result -> { @@ -100,9 +114,13 @@ public boolean handle(Request request, Response response, Callback callback) thr // Verify that after the timeout we can make another request. ContentResponse response = client.newRequest(newURI(transport)) + .body(new StringRequestContent("more data")) .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Wait for the server's idle timeout to trigger to give it a chance to clean up its resources. + assertTrue(serverIdleTimeoutLatch.await(2 * serverIdleTimeout, TimeUnit.MILLISECONDS)); } @ParameterizedTest From 27da0b942838783d57a866bf2773742736dc7489 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 18 Dec 2023 09:38:43 +0100 Subject: [PATCH 02/15] handle review comments Signed-off-by: Ludovic Orban --- .../fcgi/server/internal/ServerFCGIConnection.java | 13 ++++--------- .../java/org/eclipse/jetty/http3/HTTP3Stream.java | 2 -- .../eclipse/jetty/http3/HTTP3StreamConnection.java | 2 +- .../http3/server/internal/HttpStreamOverHTTP3.java | 1 + .../client/transport/HttpClientIdleTimeoutTest.java | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 7d649e09c118..7a079f433536 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -227,20 +227,15 @@ void parseAndFill() { if (parse(networkBuffer.getByteBuffer())) return; + // Check if the request was completed by the parsing. - if (stream == null) - { - releaseInputBuffer(); - break; - } - int filled = fillInputBuffer(); - if (filled < 0) + if (stream == null || fillInputBuffer() <= 0) { + if (LOG.isDebugEnabled()) + LOG.debug("parseAndFill completed the request by parsing {}", this); releaseInputBuffer(); break; } - if (filled == 0) - break; } } diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java index d75391fbe79a..2eadbe900122 100644 --- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java +++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java @@ -372,8 +372,6 @@ public void onTrailer(HeadersFrame frame) public void onFailure(long error, Throwable failure) { - HTTP3StreamConnection connection = (HTTP3StreamConnection)endPoint.getConnection(); - connection.onFailure(error, failure); notifyFailure(error, failure); session.removeStream(this, failure); } diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java index 9872fbe796ed..ba4923bc0726 100644 --- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java +++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java @@ -56,7 +56,7 @@ public HTTP3StreamConnection(QuicStreamEndPoint endPoint, Executor executor, Byt parser.init(MessageListener::new); } - public void onFailure(long error, Throwable failure) + public void onFailure(Throwable failure) { if (networkBuffer != null) { diff --git a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java index c3cd6e450a41..10f60737479a 100644 --- a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java +++ b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java @@ -521,6 +521,7 @@ public Runnable onFailure(Throwable failure) chunk.release(); chunk = Content.Chunk.from(failure, true); } + connection.onFailure(failure); return httpChannel.onFailure(failure); } } diff --git a/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java b/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java index 3b3b8ddbb79b..9a969015e036 100644 --- a/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java +++ b/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java @@ -37,7 +37,7 @@ public class HttpClientIdleTimeoutTest extends AbstractTest @MethodSource("transports") public void testClientIdleTimeout(Transport transport) throws Exception { - long serverIdleTimeout = idleTimeout * 3; + long serverIdleTimeout = idleTimeout * 2; CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { @@ -82,7 +82,7 @@ public boolean handle(Request request, Response response, Callback callback) @MethodSource("transports") public void testRequestIdleTimeout(Transport transport) throws Exception { - long serverIdleTimeout = idleTimeout * 3; + long serverIdleTimeout = idleTimeout * 2; CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { From 231dcfa845a717106428920b766521dd51e8f81f Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 18 Dec 2023 11:14:20 +0100 Subject: [PATCH 03/15] fix missing acquire Signed-off-by: Ludovic Orban --- .../eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 7a079f433536..9eb0054f80d0 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -221,6 +221,7 @@ void parseAndFill() { if (LOG.isDebugEnabled()) LOG.debug("parseAndFill {}", this); + acquireInputBuffer(); // This loop must run only until the request is completed. // See also HttpConnection.parseAndFillForContent(). while (stream != null) From 2bc69d229eac889be84180eb02edd0c286b4802e Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 17 Jan 2024 11:21:35 +0100 Subject: [PATCH 04/15] release the network buffer when the parser commands to stop and it is empty Signed-off-by: Ludovic Orban --- .../jetty/fcgi/server/internal/ServerFCGIConnection.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 9eb0054f80d0..f06759914cad 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -181,7 +181,11 @@ public void onFillable() if (read > 0) { if (parse(networkBuffer.getByteBuffer())) - return; + { + if (!networkBuffer.hasRemaining()) + releaseInputBuffer(); + break; + } } else if (read == 0) { From a617f3d4e1d7bfc3540cbfd1070d62107cf5fa7c Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 17 Jan 2024 11:25:00 +0100 Subject: [PATCH 05/15] release the network buffer when the parser commands to stop and it is empty Signed-off-by: Ludovic Orban --- .../jetty/fcgi/server/internal/ServerFCGIConnection.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index f06759914cad..c313ddd54de6 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -231,7 +231,11 @@ void parseAndFill() while (stream != null) { if (parse(networkBuffer.getByteBuffer())) - return; + { + if (!networkBuffer.hasRemaining()) + releaseInputBuffer(); + break; + } // Check if the request was completed by the parsing. if (stream == null || fillInputBuffer() <= 0) From 2b800a900539e3195433d033f54e03d30fe3b482 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 24 Jan 2024 11:19:06 +0100 Subject: [PATCH 06/15] fix over-releases and add comment Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index c313ddd54de6..dbcb3e405d91 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -180,12 +180,12 @@ public void onFillable() LOG.debug("Read {} bytes from {} {}", read, getEndPoint(), this); if (read > 0) { + // The networkBuffer cannot be released immediately after parse() + // even if the buffer has been fully consumed because releaseInputBuffer() + // must be called as the last release for it to be able to null out the + // networkBuffer field exactly when the latter isn't used anymore. if (parse(networkBuffer.getByteBuffer())) - { - if (!networkBuffer.hasRemaining()) - releaseInputBuffer(); break; - } } else if (read == 0) { @@ -230,12 +230,12 @@ void parseAndFill() // See also HttpConnection.parseAndFillForContent(). while (stream != null) { + // The networkBuffer cannot be released immediately after parse() + // even if the buffer has been fully consumed because releaseInputBuffer() + // must be called as the last release for it to be able to null out the + // networkBuffer field exactly when the latter isn't used anymore. if (parse(networkBuffer.getByteBuffer())) - { - if (!networkBuffer.hasRemaining()) - releaseInputBuffer(); break; - } // Check if the request was completed by the parsing. if (stream == null || fillInputBuffer() <= 0) From 7c394d92dc463fd4544f144e29b4107e87d6d77a Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Fri, 15 Dec 2023 12:52:06 +0100 Subject: [PATCH 07/15] - fix HttpClientIdleTimeoutTest to wait for server's idle timeout before checking for leaks - improve HttpClientIdleTimeoutTest by making it upload some content - fix FCGI server leak caused by idle timeout - fix H3 server leak caused by idle timeout Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 20 ++++++++++++-- .../org/eclipse/jetty/http3/HTTP3Stream.java | 2 ++ .../jetty/http3/HTTP3StreamConnection.java | 9 +++++++ .../transport/HttpClientIdleTimeoutTest.java | 26 ++++++++++++++++--- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index b38304c2420c..7d649e09c118 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -168,6 +168,8 @@ public void onOpen() @Override public void onFillable() { + if (LOG.isDebugEnabled()) + LOG.debug(">>onFillable enter {} {} {}", this, stream, networkBuffer); acquireInputBuffer(); try { @@ -203,6 +205,11 @@ else if (read == 0) releaseInputBuffer(); // TODO: fail and close ? } + finally + { + if (LOG.isDebugEnabled()) + LOG.debug("< serverIdleTimeoutLatch.countDown()); return true; } }); + connector.setIdleTimeout(serverIdleTimeout); client.setIdleTimeout(idleTimeout); CountDownLatch latch = new CountDownLatch(1); client.newRequest(newURI(transport)) .path("/timeout") + .body(new StringRequestContent("some data")) .send(result -> { if (result.isFailed()) @@ -65,15 +70,20 @@ public boolean handle(Request request, Response response, Callback callback) thr // Verify that after the timeout we can make another request. ContentResponse response = client.newRequest(newURI(transport)) .timeout(5, TimeUnit.SECONDS) + .body(new StringRequestContent("more data")) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Wait for the server's idle timeout to trigger to give it a chance to clean up its resources. + assertTrue(serverIdleTimeoutLatch.await(2 * serverIdleTimeout, TimeUnit.MILLISECONDS)); } @ParameterizedTest @MethodSource("transports") - @Tag("DisableLeakTracking:server:FCGI") public void testRequestIdleTimeout(Transport transport) throws Exception { + long serverIdleTimeout = idleTimeout * 3; + CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { @Override @@ -82,13 +92,17 @@ public boolean handle(Request request, Response response, Callback callback) thr // Do not succeed the callback if it's a timeout request. if (!Request.getPathInContext(request).equals("/timeout")) callback.succeeded(); + else + request.addFailureListener(x -> serverIdleTimeoutLatch.countDown()); return true; } }); + connector.setIdleTimeout(serverIdleTimeout); CountDownLatch latch = new CountDownLatch(1); client.newRequest(newURI(transport)) .path("/timeout") + .body(new StringRequestContent("some data")) .idleTimeout(idleTimeout, TimeUnit.MILLISECONDS) .send(result -> { @@ -100,9 +114,13 @@ public boolean handle(Request request, Response response, Callback callback) thr // Verify that after the timeout we can make another request. ContentResponse response = client.newRequest(newURI(transport)) + .body(new StringRequestContent("more data")) .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(HttpStatus.OK_200, response.getStatus()); + + // Wait for the server's idle timeout to trigger to give it a chance to clean up its resources. + assertTrue(serverIdleTimeoutLatch.await(2 * serverIdleTimeout, TimeUnit.MILLISECONDS)); } @ParameterizedTest From 8cd3f95b24895b4c3e3ce9ef4456d58fc047cbb6 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 18 Dec 2023 09:38:43 +0100 Subject: [PATCH 08/15] handle review comments Signed-off-by: Ludovic Orban --- .../fcgi/server/internal/ServerFCGIConnection.java | 13 ++++--------- .../java/org/eclipse/jetty/http3/HTTP3Stream.java | 2 -- .../eclipse/jetty/http3/HTTP3StreamConnection.java | 2 +- .../http3/server/internal/HttpStreamOverHTTP3.java | 1 + .../client/transport/HttpClientIdleTimeoutTest.java | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 7d649e09c118..7a079f433536 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -227,20 +227,15 @@ void parseAndFill() { if (parse(networkBuffer.getByteBuffer())) return; + // Check if the request was completed by the parsing. - if (stream == null) - { - releaseInputBuffer(); - break; - } - int filled = fillInputBuffer(); - if (filled < 0) + if (stream == null || fillInputBuffer() <= 0) { + if (LOG.isDebugEnabled()) + LOG.debug("parseAndFill completed the request by parsing {}", this); releaseInputBuffer(); break; } - if (filled == 0) - break; } } diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java index d75391fbe79a..2eadbe900122 100644 --- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java +++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java @@ -372,8 +372,6 @@ public void onTrailer(HeadersFrame frame) public void onFailure(long error, Throwable failure) { - HTTP3StreamConnection connection = (HTTP3StreamConnection)endPoint.getConnection(); - connection.onFailure(error, failure); notifyFailure(error, failure); session.removeStream(this, failure); } diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java index 9872fbe796ed..ba4923bc0726 100644 --- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java +++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java @@ -56,7 +56,7 @@ public HTTP3StreamConnection(QuicStreamEndPoint endPoint, Executor executor, Byt parser.init(MessageListener::new); } - public void onFailure(long error, Throwable failure) + public void onFailure(Throwable failure) { if (networkBuffer != null) { diff --git a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java index ac09155c693f..ff784c695521 100644 --- a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java +++ b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java @@ -531,6 +531,7 @@ public Runnable onFailure(Throwable failure) chunk.release(); chunk = Content.Chunk.from(failure, true); } + connection.onFailure(failure); return httpChannel.onFailure(failure); } } diff --git a/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java b/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java index 3b3b8ddbb79b..9a969015e036 100644 --- a/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java +++ b/jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java @@ -37,7 +37,7 @@ public class HttpClientIdleTimeoutTest extends AbstractTest @MethodSource("transports") public void testClientIdleTimeout(Transport transport) throws Exception { - long serverIdleTimeout = idleTimeout * 3; + long serverIdleTimeout = idleTimeout * 2; CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { @@ -82,7 +82,7 @@ public boolean handle(Request request, Response response, Callback callback) @MethodSource("transports") public void testRequestIdleTimeout(Transport transport) throws Exception { - long serverIdleTimeout = idleTimeout * 3; + long serverIdleTimeout = idleTimeout * 2; CountDownLatch serverIdleTimeoutLatch = new CountDownLatch(1); start(transport, new Handler.Abstract() { From 0c4ad22f4ca5c40a509da2d74470eede3c984f75 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Mon, 18 Dec 2023 11:14:20 +0100 Subject: [PATCH 09/15] fix missing acquire Signed-off-by: Ludovic Orban --- .../eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 7a079f433536..9eb0054f80d0 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -221,6 +221,7 @@ void parseAndFill() { if (LOG.isDebugEnabled()) LOG.debug("parseAndFill {}", this); + acquireInputBuffer(); // This loop must run only until the request is completed. // See also HttpConnection.parseAndFillForContent(). while (stream != null) From 82cda98e28f41308c665a4f6ab271a7560c69029 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 17 Jan 2024 11:21:35 +0100 Subject: [PATCH 10/15] release the network buffer when the parser commands to stop and it is empty Signed-off-by: Ludovic Orban --- .../jetty/fcgi/server/internal/ServerFCGIConnection.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 9eb0054f80d0..f06759914cad 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -181,7 +181,11 @@ public void onFillable() if (read > 0) { if (parse(networkBuffer.getByteBuffer())) - return; + { + if (!networkBuffer.hasRemaining()) + releaseInputBuffer(); + break; + } } else if (read == 0) { From 7e9ff18e08b16e75356686b7b53580a3cd3127b1 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 17 Jan 2024 11:25:00 +0100 Subject: [PATCH 11/15] release the network buffer when the parser commands to stop and it is empty Signed-off-by: Ludovic Orban --- .../jetty/fcgi/server/internal/ServerFCGIConnection.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index f06759914cad..c313ddd54de6 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -231,7 +231,11 @@ void parseAndFill() while (stream != null) { if (parse(networkBuffer.getByteBuffer())) - return; + { + if (!networkBuffer.hasRemaining()) + releaseInputBuffer(); + break; + } // Check if the request was completed by the parsing. if (stream == null || fillInputBuffer() <= 0) From 4dbd35a7f1480ff7ecfcdb2530e8e9b1a44a3ed6 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 24 Jan 2024 11:19:06 +0100 Subject: [PATCH 12/15] fix over-releases and add comment Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index c313ddd54de6..dbcb3e405d91 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -180,12 +180,12 @@ public void onFillable() LOG.debug("Read {} bytes from {} {}", read, getEndPoint(), this); if (read > 0) { + // The networkBuffer cannot be released immediately after parse() + // even if the buffer has been fully consumed because releaseInputBuffer() + // must be called as the last release for it to be able to null out the + // networkBuffer field exactly when the latter isn't used anymore. if (parse(networkBuffer.getByteBuffer())) - { - if (!networkBuffer.hasRemaining()) - releaseInputBuffer(); break; - } } else if (read == 0) { @@ -230,12 +230,12 @@ void parseAndFill() // See also HttpConnection.parseAndFillForContent(). while (stream != null) { + // The networkBuffer cannot be released immediately after parse() + // even if the buffer has been fully consumed because releaseInputBuffer() + // must be called as the last release for it to be able to null out the + // networkBuffer field exactly when the latter isn't used anymore. if (parse(networkBuffer.getByteBuffer())) - { - if (!networkBuffer.hasRemaining()) - releaseInputBuffer(); break; - } // Check if the request was completed by the parsing. if (stream == null || fillInputBuffer() <= 0) From 67b5c5d64b8ba9200fc21991c65d07bb3be13ea6 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Thu, 22 Feb 2024 15:25:16 +0100 Subject: [PATCH 13/15] handle review comments Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 38 +++++----- .../jetty/http3/HTTP3StreamConnection.java | 76 +++++++++---------- 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index dbcb3e405d91..5b52c16e1320 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -48,12 +48,11 @@ public class ServerFCGIConnection extends AbstractMetaDataConnection implements private final ByteBufferPool networkByteBufferPool; private final boolean sendStatus200; private final Flusher flusher; - private final HttpConfiguration configuration; private final ServerParser parser; private final String id; private boolean useInputDirectByteBuffers; private boolean useOutputDirectByteBuffers; - private RetainableByteBuffer networkBuffer; + private RetainableByteBuffer inputBuffer; private HttpStreamOverFCGI stream; public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfiguration configuration, boolean sendStatus200) @@ -62,7 +61,6 @@ public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfigur this.connector = connector; this.networkByteBufferPool = connector.getByteBufferPool(); this.flusher = new Flusher(endPoint); - this.configuration = configuration; this.sendStatus200 = sendStatus200; this.parser = new ServerParser(new ServerListener()); this.id = StringUtil.randomAlphaNumeric(16); @@ -169,7 +167,7 @@ public void onOpen() public void onFillable() { if (LOG.isDebugEnabled()) - LOG.debug(">>onFillable enter {} {} {}", this, stream, networkBuffer); + LOG.debug(">>onFillable enter {} {} {}", this, stream, inputBuffer); acquireInputBuffer(); try { @@ -184,20 +182,20 @@ public void onFillable() // even if the buffer has been fully consumed because releaseInputBuffer() // must be called as the last release for it to be able to null out the // networkBuffer field exactly when the latter isn't used anymore. - if (parse(networkBuffer.getByteBuffer())) - break; + if (parse(inputBuffer.getByteBuffer())) + return; } else if (read == 0) { releaseInputBuffer(); fillInterested(); - break; + return; } else { releaseInputBuffer(); shutdown(); - break; + return; } } } @@ -205,14 +203,14 @@ else if (read == 0) { if (LOG.isDebugEnabled()) LOG.debug("Unable to fill endpoint", x); - networkBuffer.clear(); + inputBuffer.clear(); releaseInputBuffer(); // TODO: fail and close ? } finally { if (LOG.isDebugEnabled()) - LOG.debug("< tryReleaseBuffer(false); + case NO_FRAME -> tryReleaseInputBuffer(false); case SWITCH_MODE -> { parser.setDataMode(false); @@ -141,14 +139,14 @@ private void processDataFrames(boolean setFillInterest) { // The last frame may have caused a write that we need to flush. getEndPoint().getQuicSession().flush(); - tryReleaseBuffer(false); + tryReleaseInputBuffer(false); } } } } catch (Throwable x) { - tryReleaseBuffer(true); + tryReleaseInputBuffer(true); long error = HTTP3ErrorCode.REQUEST_CANCELLED_ERROR.code(); getEndPoint().close(error, x); // Notify the application that a failure happened. @@ -160,7 +158,7 @@ private void processNonDataFrames() { try { - tryAcquireBuffer(); + tryAcquireInputBuffer(); while (true) { @@ -169,14 +167,14 @@ private void processNonDataFrames() { case NO_FRAME -> { - tryReleaseBuffer(false); + tryReleaseInputBuffer(false); return; } case BLOCKED_FRAME -> { // Return immediately because another thread may // resume the processing as the stream is unblocked. - tryReleaseBuffer(false); + tryReleaseInputBuffer(false); return; } case SWITCH_MODE -> @@ -201,7 +199,7 @@ private void processNonDataFrames() // However, the last frame may have // caused a write that we need to flush. getEndPoint().getQuicSession().flush(); - tryReleaseBuffer(false); + tryReleaseInputBuffer(false); return; } @@ -210,7 +208,7 @@ private void processNonDataFrames() if (stream.hasDemandOrStall()) { - if (networkBuffer != null && networkBuffer.hasRemaining()) + if (inputBuffer != null && inputBuffer.hasRemaining()) { // There are bytes left in the buffer; if there are not // enough bytes to parse a DATA frame and call the @@ -221,7 +219,7 @@ private void processNonDataFrames() { // No bytes left in the buffer, but there is demand. // Set fill interest to call the application when bytes arrive. - tryReleaseBuffer(false); + tryReleaseInputBuffer(false); fillInterested(); } } @@ -236,7 +234,7 @@ private void processNonDataFrames() } catch (Throwable x) { - tryReleaseBuffer(true); + tryReleaseInputBuffer(true); long error = HTTP3ErrorCode.REQUEST_CANCELLED_ERROR.code(); getEndPoint().close(error, x); // Notify the application that a failure happened. @@ -251,28 +249,28 @@ public void receive() processDataFrames(false); } - private void tryAcquireBuffer() + private void tryAcquireInputBuffer() { - if (networkBuffer == null) + if (inputBuffer == null) { - networkBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); + inputBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); if (LOG.isDebugEnabled()) - LOG.debug("acquired {}", networkBuffer); + LOG.debug("acquired {}", inputBuffer); } } - private void tryReleaseBuffer(boolean force) + private void tryReleaseInputBuffer(boolean force) { - if (networkBuffer != null) + if (inputBuffer != null) { - if (networkBuffer.hasRemaining() && force) - networkBuffer.clear(); - if (!networkBuffer.hasRemaining()) + if (inputBuffer.hasRemaining() && force) + inputBuffer.clear(); + if (!inputBuffer.hasRemaining()) { - networkBuffer.release(); + inputBuffer.release(); if (LOG.isDebugEnabled()) - LOG.debug("released {}", networkBuffer); - networkBuffer = null; + LOG.debug("released {}", inputBuffer); + inputBuffer = null; } } } @@ -282,30 +280,30 @@ private MessageParser.Result parseAndFill(boolean setFillInterest) try { if (LOG.isDebugEnabled()) - LOG.debug("parse+fill setFillInterest={} on {} with buffer {}", setFillInterest, this, networkBuffer); + LOG.debug("parse+fill setFillInterest={} on {} with buffer {}", setFillInterest, this, inputBuffer); while (true) { - ByteBuffer byteBuffer = networkBuffer.getByteBuffer(); + ByteBuffer byteBuffer = inputBuffer.getByteBuffer(); MessageParser.Result result = parser.parse(byteBuffer); if (LOG.isDebugEnabled()) - LOG.debug("parsed {} on {} with buffer {}", result, this, networkBuffer); + LOG.debug("parsed {} on {} with buffer {}", result, this, inputBuffer); if (result != MessageParser.Result.NO_FRAME) return result; - if (networkBuffer.isRetained()) + if (inputBuffer.isRetained()) { - networkBuffer.release(); + inputBuffer.release(); RetainableByteBuffer newBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); if (LOG.isDebugEnabled()) - LOG.debug("reacquired {} for retained {}", newBuffer, networkBuffer); - networkBuffer = newBuffer; - byteBuffer = networkBuffer.getByteBuffer(); + LOG.debug("reacquired {} for retained {}", newBuffer, inputBuffer); + inputBuffer = newBuffer; + byteBuffer = inputBuffer.getByteBuffer(); } int filled = fill(byteBuffer); if (LOG.isDebugEnabled()) - LOG.debug("filled {} on {} with buffer {}", filled, this, networkBuffer); + LOG.debug("filled {} on {} with buffer {}", filled, this, inputBuffer); if (filled > 0) continue; @@ -406,7 +404,7 @@ private void processData(DataFrame frame, Runnable delegate) { // No need to call networkBuffer.retain() here, since we know // that the action will be run before releasing the networkBuffer. - data = new StreamData(frame, networkBuffer); + data = new StreamData(frame, inputBuffer); } delegate.run(); From c783fcb4c73c025f9b76ac2374b8af2290a2094e Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 22 Feb 2024 15:51:55 +0100 Subject: [PATCH 14/15] Using the input buffer size for the network buffer. Signed-off-by: Simone Bordet --- .../jetty/fcgi/server/internal/ServerFCGIConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index 5b52c16e1320..c161eff41d4b 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -249,7 +249,7 @@ void parseAndFill() private void acquireInputBuffer() { if (inputBuffer == null) - inputBuffer = networkByteBufferPool.acquire(getHttpConfiguration().getResponseHeaderSize(), isUseInputDirectByteBuffers()); + inputBuffer = networkByteBufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); } private void releaseInputBuffer() From 2bd8896defb1f5a05ce9e022f50bdc90147296ea Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Thu, 22 Feb 2024 15:53:45 +0100 Subject: [PATCH 15/15] handle review comments Signed-off-by: Ludovic Orban --- .../server/internal/ServerFCGIConnection.java | 16 ++++++++-------- .../jetty/http3/HTTP3StreamConnection.java | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java index c161eff41d4b..95a0fbd14d86 100644 --- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java +++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java @@ -45,7 +45,7 @@ public class ServerFCGIConnection extends AbstractMetaDataConnection implements private final HttpChannel.Factory httpChannelFactory = new HttpChannel.DefaultFactory(); private final Attributes attributes = new Lazy(); private final Connector connector; - private final ByteBufferPool networkByteBufferPool; + private final ByteBufferPool bufferPool; private final boolean sendStatus200; private final Flusher flusher; private final ServerParser parser; @@ -59,7 +59,7 @@ public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfigur { super(connector, configuration, endPoint); this.connector = connector; - this.networkByteBufferPool = connector.getByteBufferPool(); + this.bufferPool = connector.getByteBufferPool(); this.flusher = new Flusher(endPoint); this.sendStatus200 = sendStatus200; this.parser = new ServerParser(new ServerListener()); @@ -178,10 +178,10 @@ public void onFillable() LOG.debug("Read {} bytes from {} {}", read, getEndPoint(), this); if (read > 0) { - // The networkBuffer cannot be released immediately after parse() + // The inputBuffer cannot be released immediately after parse() // even if the buffer has been fully consumed because releaseInputBuffer() // must be called as the last release for it to be able to null out the - // networkBuffer field exactly when the latter isn't used anymore. + // inputBuffer field exactly when the latter isn't used anymore. if (parse(inputBuffer.getByteBuffer())) return; } @@ -228,10 +228,10 @@ void parseAndFill() // See also HttpConnection.parseAndFillForContent(). while (stream != null) { - // The networkBuffer cannot be released immediately after parse() + // The inputBuffer cannot be released immediately after parse() // even if the buffer has been fully consumed because releaseInputBuffer() // must be called as the last release for it to be able to null out the - // networkBuffer field exactly when the latter isn't used anymore. + // inputBuffer field exactly when the latter isn't used anymore. if (parse(inputBuffer.getByteBuffer())) return; @@ -249,7 +249,7 @@ void parseAndFill() private void acquireInputBuffer() { if (inputBuffer == null) - inputBuffer = networkByteBufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); + inputBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers()); } private void releaseInputBuffer() @@ -369,7 +369,7 @@ public boolean onContent(int request, FCGI.StreamType streamType, ByteBuffer buf LOG.debug("Request {} {} content {} on {}", request, streamType, buffer, stream); if (stream != null) { - // No need to call networkBuffer.retain() here. + // No need to call inputBuffer.retain() here. // The receiver of the chunk decides whether to consume/retain it. Content.Chunk chunk = Content.Chunk.asChunk(buffer, false, inputBuffer); stream.onContent(chunk); diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java index 5dec90f098ad..29542da3d1eb 100644 --- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java +++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java @@ -402,8 +402,8 @@ private void processData(DataFrame frame, Runnable delegate) } else { - // No need to call networkBuffer.retain() here, since we know - // that the action will be run before releasing the networkBuffer. + // No need to call inputBuffer.retain() here, since we know + // that the action will be run before releasing the inputBuffer. data = new StreamData(frame, inputBuffer); }