HTTP/2 Decoder validate that GOAWAY lastStreamId doesn't increase

Motivation:
The HTTP/2 RFC states in https://tools.ietf.org/html/rfc7540#section-6.8 that Endpoints MUST NOT increase the value they send in the last stream identifier however we don't enforce this when decoding GOAWAY frames.

Modifications:
- Throw a connection error if the peer attempts to increase the lastStreamId in a GOAWAY frame

Result:
RFC is more strictly enforced.
This commit is contained in:
Scott Mitchell 2016-06-25 13:34:10 -07:00
parent 3613d15bca
commit df41be6fc8
2 changed files with 11 additions and 0 deletions

View File

@ -182,6 +182,10 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
void onGoAwayRead0(ChannelHandlerContext ctx, int lastStreamId, long errorCode, ByteBuf debugData)
throws Http2Exception {
if (connection.goAwayReceived() && connection.local().lastStreamKnownByPeer() < lastStreamId) {
throw connectionError(PROTOCOL_ERROR, "lastStreamId MUST NOT increase. Current value: %d new value: %d",
connection.local().lastStreamKnownByPeer(), lastStreamId);
}
listener.onGoAwayRead(ctx, lastStreamId, errorCode, debugData);
connection.goAwayReceived(lastStreamId, errorCode, debugData);
}

View File

@ -628,6 +628,13 @@ public class DefaultHttp2ConnectionDecoderTest {
verify(listener).onRstStreamRead(eq(ctx), anyInt(), anyLong());
}
@Test(expected = Http2Exception.class)
public void goawayIncreasedLastStreamIdShouldThrow() throws Exception {
when(local.lastStreamKnownByPeer()).thenReturn(1);
when(connection.goAwayReceived()).thenReturn(true);
decode().onGoAwayRead(ctx, 3, 2L, EMPTY_BUFFER);
}
@Test(expected = Http2Exception.class)
public void rstStreamReadForUnknownStreamShouldThrow() throws Exception {
when(connection.streamMayHaveExisted(STREAM_ID)).thenReturn(false);