diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java index bd9d2373b0..731a960177 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoder.java @@ -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); } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoderTest.java index cfca1f8437..50b74cc878 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/DefaultHttp2ConnectionDecoderTest.java @@ -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);