Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions java/org/apache/coyote/http2/Http2UpgradeHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
private final PingManager pingManager = getPingManager();
private volatile int newStreamsSinceLastPrune = 0;
private final Set<Stream> backLogStreams = new HashSet<>();
// The sum of the connection allocations requested by the streams in backLogStreams. Any change to a stream's
// requested allocation must be mirrored here so releaseBackLog() can correctly determine whether an increment
// clears the backlog.
private long backLogSize = 0;
// The time at which the connection will timeout unless data arrives before
// then. -1 means no timeout.
Expand Down Expand Up @@ -1332,6 +1335,7 @@ private int allocate(AbstractStream stream, int allocation) {
int allocatedThisTime = Math.min(allocation, stream.getConnectionAllocationRequested());
stream.setConnectionAllocationRequested(stream.getConnectionAllocationRequested() - allocatedThisTime);
stream.setConnectionAllocationMade(stream.getConnectionAllocationMade() + allocatedThisTime);
backLogSize -= allocatedThisTime;
leftToAllocate = leftToAllocate - allocatedThisTime;
}

Expand Down
25 changes: 24 additions & 1 deletion test/org/apache/coyote/http2/TestRfc9218.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void testPriority() throws Exception {
trace = trace.replace("21-Body-1365\n", "");
Assert.assertEquals(0, trace.length());

// 19 - 5641 body left
// 19 - 5461 body left
// 21 - 4778 body left

// Add 16k to the connection window. Should fully allocate 19 and 21.
Expand All @@ -200,6 +200,29 @@ public void testPriority() throws Exception {
// Dump for debugging purposes
ioe.printStackTrace();
}

output.clearTrace();

/*
* The final window update was 6145 bytes larger than the outstanding backlog. Those bytes must remain available
* in the connection window for the next stream.
*/
sendSimpleGetRequest(23);
parser.readFrame();
// The headers for stream 23 will always arrive. If the surplus was lost, no body will be sent and the read
// below would block for the default timeout - so use a short timeout to fail quickly.
s.setSoTimeout(1000);
parser.readFrame();

Assert.assertTrue(output.getTrace().contains("23-Body-6145\n"));
output.clearTrace();

// 2047 completes the 8192 byte response body for stream 23, confirming that exactly 6145 surplus bytes were
// available in the connection window.
sendWindowUpdate(0, 2047);
parser.readFrame();

Assert.assertEquals("23-Body-2047\n23-EndOfStream\n", output.getTrace());
}


Expand Down