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 7ecbffd Fix a possible connection stall during concurrent stream write
7ecbffd is described below
commit 7ecbffdc8c391f78af3570dd22e64c93aabd8f8b
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Jul 1 19:24:06 2021 +0100
Fix a possible connection stall during concurrent stream write
The stall could occur in the following circumstances:
- all current streams were in the backlog and received partial
allocations
- not all streams have acted on their allocation (i.e. the connection
window size is currently >0)
- one or more window updates arrive for the connection before the
connection window size reaches zero
- no further window updates are received after the window size reaches
zero
This could be recreated with a simple HTML page that loaded three large
(1MB) images when called with "nghttp -vnsay
https://localhost:8443/test/index.html"
---
java/org/apache/coyote/http2/Http2UpgradeHandler.java | 14 +++++++++++++-
webapps/docs/changelog.xml | 11 +++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index e990f41..b994e92 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -983,7 +983,17 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
synchronized (this) {
long windowSize = getWindowSize();
if (windowSize < 1 && windowSize + increment > 0) {
+ // Connection window is completed exhausted. Assume there will
+ // be streams to notify. The overhead is minimal if there are
+ // none.
streamsToNotify = releaseBackLog((int) (windowSize
+increment));
+ } else if (backLogSize > 0) {
+ // While windowSize is greater than zero, all of it has already
+ // been allocated to streams in the backlog (or just about to
+ // exit the backlog). If any of windowSize was unallocated or
+ // 'spare', backLogSize would be zero. Therefore, apply this
+ // addition allocation to the backlog.
+ streamsToNotify = releaseBackLog(increment);
}
super.incrementWindowSize(increment);
}
@@ -1061,7 +1071,9 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
// Loop until we run out of allocation or recipients
while (leftToAllocate > 0) {
if (recipients.size() == 0) {
- backLogStreams.remove(stream);
+ if (tracker.getUnusedAllocation() == 0) {
+ backLogStreams.remove(stream);
+ }
return leftToAllocate;
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ad85d11..7445db5 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -114,6 +114,17 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Coyote">
+ <changelog>
+ <fix>
+ Correct bugs in the HTTP/2 connection flow control management that
meant
+ it was possible for a connection to stall waiting for a connection flow
+ control window update that had already arrived. Any streams on that
+ connection that were trying to write when this happened would time out.
+ (markt)
+ </fix>
+ </changelog>
+ </subsection>
</section>
<section name="Tomcat 8.5.69 (schultz)" rtext="in progress">
<subsection name="Catalina">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]