Move check for current streams to end of header parsing. · apache/tomcat@1bbc650 · GitHub
Skip to content

Commit

Permalink
Move check for current streams to end of header parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Aug 17, 2020
1 parent 7138fa9 commit 1bbc650
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
2 changes: 1 addition & 1 deletion java/org/apache/coyote/http2/Http2Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ static interface Output {
HeaderEmitter headersStart(int streamId, boolean headersEndStream)
throws Http2Exception, IOException;
void headersContinue(int payloadSize, boolean endOfHeaders);
void headersEnd(int streamId) throws ConnectionException;
void headersEnd(int streamId) throws Http2Exception;

// Priority frames (also headers)
void reprioritise(int streamId, int parentStreamId, boolean exclusive, int weight)
Expand Down
24 changes: 13 additions & 11 deletions java/org/apache/coyote/http2/Http2UpgradeHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -1450,16 +1450,6 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream)
stream.checkState(FrameType.HEADERS);
stream.receivedStartOfHeaders(headersEndStream);
closeIdleStreams(streamId);
if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
// Ignoring maxConcurrentStreams increases the overhead count
increaseOverheadCount();
throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
Long.toString(localSettings.getMaxConcurrentStreams())),
Http2Error.REFUSED_STREAM, streamId);
}
// Valid new stream reduces the overhead count
reduceOverheadCount();
return stream;
} else {
if (log.isDebugEnabled()) {
Expand Down Expand Up @@ -1527,12 +1517,24 @@ public void headersContinue(int payloadSize, boolean endOfHeaders) {


@Override
public void headersEnd(int streamId) throws ConnectionException {
public void headersEnd(int streamId) throws Http2Exception {
Stream stream = getStream(streamId, connectionState.get().isNewStreamAllowed());
if (stream != null) {
setMaxProcessedStream(streamId);
if (stream.isActive()) {
if (stream.receivedEndOfHeaders()) {

if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
// Ignoring maxConcurrentStreams increases the overhead count
increaseOverheadCount();
throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
Long.toString(localSettings.getMaxConcurrentStreams())),
Http2Error.REFUSED_STREAM, streamId);
}
// Valid new stream reduces the overhead count
reduceOverheadCount();

processStreamOnContainerThread(stream);
}
}
Expand Down
20 changes: 13 additions & 7 deletions test/org/apache/coyote/http2/TestHttp2Section_5_1.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ public void testExceedMaxActiveStreams() throws Exception {
// Expecting
// 1 * headers
// 56k-1 of body (7 * ~8k)
// 1 * error (could be in any order)
for (int i = 0; i < 8; i++) {
// 1 * error
// for a total of 9 frames (could be in any order)
for (int i = 0; i < 9; i++) {
parser.readFrame(true);
}
parser.readFrame(true);

Assert.assertTrue(output.getTrace(),
output.getTrace().contains("5-RST-[" +
Expand All @@ -238,14 +238,20 @@ public void testExceedMaxActiveStreams() throws Exception {

// Release the remaining body
sendWindowUpdate(0, (1 << 31) - 2);
// Allow for the 8k still in the stream window
// Allow for the ~8k still in the stream window
sendWindowUpdate(3, (1 << 31) - 8193);

// 192k of body (24 * 8k)
// 1 * error (could be in any order)
for (int i = 0; i < 24; i++) {
// Read until the end of stream 3
while (!output.getTrace().contains("3-EndOfStream")) {
parser.readFrame(true);
}
output.clearTrace();

// Confirm another request can be sent once concurrency falls back below limit
sendSimpleGetRequest(7);
parser.readFrame(true);
parser.readFrame(true);
Assert.assertEquals(getSimpleResponseTrace(7), output.getTrace());
}


Expand Down

0 comments on commit 1bbc650

Please sign in to comment.