This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push:
new 7f748eb Expand HTTP/2 timeout handling to connection window
exhaustion on write.
7f748eb is described below
commit 7f748eb6bfaba5207c89dbd7d5adf50fae847145
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Apr 30 22:18:12 2019 +0100
Expand HTTP/2 timeout handling to connection window exhaustion on write.
---
.../apache/coyote/http2/Http2UpgradeHandler.java | 32 ++++++++++++++++++++--
java/org/apache/coyote/http2/Stream.java | 27 ++++++++++--------
webapps/docs/changelog.xml | 4 +++
3 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index a787349..58620fd 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -801,7 +801,26 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
if (allocation == 0) {
if (block) {
try {
- stream.wait();
+ // Connection level window is empty. Although this
+ // request is for a stream, use the connection
+ // timeout
+ long writeTimeout = protocol.getWriteTimeout();
+ if (writeTimeout < 0) {
+ stream.wait();
+ } else {
+ stream.wait(writeTimeout);
+ }
+ // Has this stream been granted an allocation
+ int[] value = backLogStreams.get(stream);
+ if (value[1] == 0) {
+ // No allocation
+ // Close the connection. Do this first since
+ // closing the stream will raise an exception
+ close();
+ // Close the stream (in app code so need to
+ // signal to app stream is closing)
+ stream.doWriteTimeout();
+ }
} catch (InterruptedException e) {
throw new IOException(sm.getString(
"upgradeHandler.windowSizeReservationInterrupted", connectionId,
@@ -1024,11 +1043,20 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
private void close() {
- connectionState.set(ConnectionState.CLOSED);
+ ConnectionState previous =
connectionState.getAndSet(ConnectionState.CLOSED);
+ if (previous == ConnectionState.CLOSED) {
+ // Already closed
+ return;
+ }
+
for (Stream stream : streams.values()) {
// The connection is closing. Close the associated streams as no
// longer required.
stream.receiveReset(Http2Error.CANCEL.getCode());
+ // Release any streams waiting for an allocation
+ synchronized (stream) {
+ stream.notifyAll();
+ }
}
try {
socketWrapper.close();
diff --git a/java/org/apache/coyote/http2/Stream.java
b/java/org/apache/coyote/http2/Stream.java
index 408a144..3f36c56 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -283,17 +283,7 @@ class Stream extends AbstractStream implements
HeaderEmitter {
}
windowSize = getWindowSize();
if (windowSize == 0) {
- String msg = sm.getString("stream.writeTimeout");
- StreamException se = new StreamException(
- msg, Http2Error.ENHANCE_YOUR_CALM,
getIdAsInt());
- // Prevent the application making further writes
- streamOutputBuffer.closed = true;
- // Prevent Tomcat's error handling trying to write
- coyoteResponse.setError();
- coyoteResponse.setErrorReported();
- // Trigger a reset once control returns to Tomcat
- streamOutputBuffer.reset = se;
- throw new CloseNowException(msg, se);
+ doWriteTimeout();
}
} catch (InterruptedException e) {
// Possible shutdown / rst or similar. Use an IOException
to
@@ -316,6 +306,21 @@ class Stream extends AbstractStream implements
HeaderEmitter {
}
+ void doWriteTimeout() throws CloseNowException {
+ String msg = sm.getString("stream.writeTimeout");
+ StreamException se = new StreamException(
+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
+ // Prevent the application making further writes
+ streamOutputBuffer.closed = true;
+ // Prevent Tomcat's error handling trying to write
+ coyoteResponse.setError();
+ coyoteResponse.setErrorReported();
+ // Trigger a reset once control returns to Tomcat
+ streamOutputBuffer.reset = se;
+ throw new CloseNowException(msg, se);
+ }
+
+
@Override
public final void emitHeader(String name, String value) throws
HpackException {
if (log.isDebugEnabled()) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 8518b64..228e867 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -171,6 +171,10 @@
for possible use with an asynchronous workflow like CompletableFuture.
(remm)
</update>
+ <fix>
+ Expand HTTP/2 timeout handling to include connection window exhaustion
+ on write. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]