This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push: new 52f007711c Ensure onAllDataRead() fires with chunked request body 52f007711c is described below commit 52f007711c73c4733c9acf4c53d988f193853306 Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue Apr 23 13:48:49 2024 +0100 Ensure onAllDataRead() fires with chunked request body --- .../coyote/http11/filters/ChunkedInputFilter.java | 15 ++++++++ .../catalina/nonblocking/TestNonBlockingAPI.java | 45 ++++++++++++++++++++++ webapps/docs/changelog.xml | 5 +++ 3 files changed, 65 insertions(+) diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java index 13dcb7d53f..c0b74a185f 100644 --- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -24,6 +24,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import org.apache.coyote.ActionCode; import org.apache.coyote.BadRequestException; import org.apache.coyote.InputBuffer; import org.apache.coyote.Request; @@ -167,6 +168,20 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler } if (endChunk) { parseEndChunk(); + if (!request.isRequestThread()) { + /* + * Perform the dispatch back to the container for the onAllDataRead() event. For non-chunked input + * this would be performed when isReady() is next called. + * + * Chunked input returns one chunk at a time for non-blocking reads. A consequence of this is that + * reading the final chunk returns -1 which signals the end of stream. The application code reading + * the request body probably won't call isReady() after receiving the -1 return value since it + * already knows it is at end of stream. Therefore we trigger the dispatch back to the container + * here which in turn ensures the onAllDataRead() event is fired. + */ + request.action(ActionCode.DISPATCH_READ, null); + request.action(ActionCode.DISPATCH_EXECUTE, null); + } return -1; } } diff --git a/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java b/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java index c86a500239..eca6090712 100644 --- a/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java +++ b/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java @@ -154,6 +154,51 @@ public class TestNonBlockingAPI extends TomcatBaseTest { } + @Test + public void testNonBlockingReadChunked() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // No file system docBase required + Context ctx = getProgrammaticRootContext(); + + NBReadServlet servlet = new NBReadServlet(false, true); + String servletName = NBReadServlet.class.getName(); + Tomcat.addServlet(ctx, servletName, servlet); + ctx.addServletMappingDecoded("/", servletName); + + tomcat.start(); + + Client client = new Client(); + client.setPort(getPort()); + client.setRequest(new String[] { "GET / HTTP/1.1" + SimpleHttpClient.CRLF + + "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + + "Transfer-Encoding: chunked" + SimpleHttpClient.CRLF + + SimpleHttpClient.CRLF + + "14" + SimpleHttpClient.CRLF + + "01234567890123456789" + SimpleHttpClient.CRLF + + "14" + SimpleHttpClient.CRLF + + "012345678901FINISHED" + SimpleHttpClient.CRLF + + "0" + SimpleHttpClient.CRLF + + SimpleHttpClient.CRLF}); + client.connect(); + client.sendRequest(); + + client.setUseContentLength(true); + client.readResponse(true); + + Assert.assertTrue(client.isResponse200()); + Assert.assertTrue(client.isResponseBodyOK()); + } + + + private static class Client extends SimpleHttpClient { + @Override + public boolean isResponseBodyOK() { + return "OK".equals(getResponseBody()); + } + } + + @Test public void testNonBlockingWrite() throws Exception { testNonBlockingWriteInternal(false); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index c2a903f944..036fed1454 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -164,6 +164,11 @@ failed. The wait time is now 100ms plus twice <code>socket.unlockTimeout</code>. (markt) </fix> + <fix> + Ensure that the <code>onAllDataRead()</code> event is triggered when the + request body uses chunked encoding and is read using non-blocking IO. + (markt) + </fix> </changelog> </subsection> <subsection name="Other"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org