This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/8.5.x by this push: new 8654a1c Fix the HTTP/2 equivalent of swallowInput 8654a1c is described below commit 8654a1c3da02fbaf964992edc91391197f613d3e Author: Mark Thomas <ma...@apache.org> AuthorDate: Sun Apr 7 21:39:15 2019 +0100 Fix the HTTP/2 equivalent of swallowInput When Tomcat writes a final response without reading all of an HTTP/2 request, reset the stream to inform the client that the remaining request body is not required. --- java/org/apache/coyote/AbstractProcessor.java | 7 +++++-- java/org/apache/coyote/AbstractProcessorLight.java | 10 +++++++-- .../apache/coyote/http2/LocalStrings.properties | 1 + java/org/apache/coyote/http2/StreamProcessor.java | 24 +++++++++++++++++++++- webapps/docs/changelog.xml | 5 +++++ 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/java/org/apache/coyote/AbstractProcessor.java b/java/org/apache/coyote/AbstractProcessor.java index d5d4cca..9af075b 100644 --- a/java/org/apache/coyote/AbstractProcessor.java +++ b/java/org/apache/coyote/AbstractProcessor.java @@ -202,7 +202,7 @@ public abstract class AbstractProcessor extends AbstractProcessorLight implement @Override - public final SocketState dispatch(SocketEvent status) { + public final SocketState dispatch(SocketEvent status) throws IOException { if (status == SocketEvent.OPEN_WRITE && response.getWriteListener() != null) { asyncStateMachine.asyncOperation(); @@ -928,6 +928,9 @@ public abstract class AbstractProcessor extends AbstractProcessorLight implement * * @return The state to return for the socket once the clean-up for the * current request has completed + * + * @throws IOException If an I/O error occurs while attempting to end the + * request */ - protected abstract SocketState dispatchEndRequest(); + protected abstract SocketState dispatchEndRequest() throws IOException; } diff --git a/java/org/apache/coyote/AbstractProcessorLight.java b/java/org/apache/coyote/AbstractProcessorLight.java index 340c986..7a46c79 100644 --- a/java/org/apache/coyote/AbstractProcessorLight.java +++ b/java/org/apache/coyote/AbstractProcessorLight.java @@ -152,10 +152,16 @@ public abstract class AbstractProcessorLight implements Processor { * Uses currently include Servlet 3.0 Async and HTTP upgrade connections. * Further uses may be added in the future. These will typically start as * HTTP requests. + * * @param status The event to process - * @return the socket state + * + * @return The state the caller should put the socket in when this method + * returns + * + * @throws IOException If an I/O error occurs during the processing of the + * request */ - protected abstract SocketState dispatch(SocketEvent status); + protected abstract SocketState dispatch(SocketEvent status) throws IOException; protected abstract SocketState asyncPostProcess(); diff --git a/java/org/apache/coyote/http2/LocalStrings.properties b/java/org/apache/coyote/http2/LocalStrings.properties index c47e402..24a7d1a 100644 --- a/java/org/apache/coyote/http2/LocalStrings.properties +++ b/java/org/apache/coyote/http2/LocalStrings.properties @@ -103,6 +103,7 @@ stream.inputBuffer.signal=Data added to inBuffer when read thread is waiting. Si stream.outputBuffer.flush.debug=Connection [{0}], Stream [{1}], flushing output with buffer at position [{2}], writeInProgress [{3}] and closed [{4}] +streamProcessor.cancel=Connection [{0}], Stream [{1}], The remaining request body is not required. streamProcessor.error.connection=Connection [{0}], Stream [{1}], An error occurred during processing that was fatal to the connection streamProcessor.error.stream=Connection [{0}], Stream [{1}], An error occurred during processing that was fatal to the stream streamProcessor.flushBufferedWrite.entry=Connection [{0}], Stream [{1}], Flushing buffered writes diff --git a/java/org/apache/coyote/http2/StreamProcessor.java b/java/org/apache/coyote/http2/StreamProcessor.java index a6c8187..c44103e 100644 --- a/java/org/apache/coyote/http2/StreamProcessor.java +++ b/java/org/apache/coyote/http2/StreamProcessor.java @@ -323,6 +323,13 @@ class StreamProcessor extends AbstractProcessor { setErrorState(ErrorState.CLOSE_NOW, e); } + if (!isAsync()) { + // If this is an async request then the request ends when it has + // been completed. The AsyncContext is responsible for calling + // endRequest() in that case. + endRequest(); + } + if (getErrorState().isError()) { action(ActionCode.CLOSE, null); request.updateCounters(); @@ -362,7 +369,22 @@ class StreamProcessor extends AbstractProcessor { @Override - protected SocketState dispatchEndRequest() { + protected final SocketState dispatchEndRequest() throws IOException { + endRequest(); return SocketState.CLOSED; } + + + private void endRequest() throws IOException { + if (!stream.isInputFinished()) { + // The request has been processed but the request body has not been + // fully read. This typically occurs when Tomcat rejects an upload + // of some form (e.g. PUT or POST). Need to tell the client not to + // send any more data. + StreamException se = new StreamException( + sm.getString("streamProcessor.cancel", stream.getConnectionId(), + stream.getIdentifier()), Http2Error.CANCEL, stream.getIdAsInt()); + handler.sendStreamReset(se); + } + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 5acdd2f..b087a89 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -114,6 +114,11 @@ query string present in the original HTTP/1.1 request is passed to the HTTP/2 request processing. (markt) </fix> + <fix> + When Tomcat writes a final response without reading all of an HTTP/2 + request, reset the stream to inform the client that the remaining + request body is not required. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org