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 0bcd69c  Expand HTTP/2 timeout handling to connection window 
exhaustion on write.
0bcd69c is described below

commit 0bcd69c9dd8ae0ff424f2cd46de51583510b7f35
Author: Mark Thomas <ma...@apache.org>
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 86f0e93..e5ae91f 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -805,7 +805,26 @@ public class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpU
                 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,
@@ -1023,11 +1042,20 @@ public class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpU
 
 
     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 1c6ed9d..d7b2006 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -280,17 +280,7 @@ public 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
@@ -313,6 +303,21 @@ public 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
     @Deprecated
     protected synchronized void doNotifyAll() {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 72c1424..24a4b9a 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -113,6 +113,10 @@
         Refactor Hostname validation to improve performance. Patch provided by
         Uwe Hees. (markt)
       </scode>
+      <fix>
+        Expand HTTP/2 timeout handling to include connection window exhaustion
+        on write. (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

Reply via email to