HTTP/2 RST_STREAM in IDLE
Motivation: The spec requires that a RST_STREAM received on an IDLE stream results in a connection error. This is not happening. Modifications: Check for this condition when a RST_STREAM is received in DefaultHttp2ConnectionDecoder. Result: More spec compliant. Fixes https://github.com/netty/netty/issues/3573.
This commit is contained in:
parent
e5d01c4caf
commit
9517edd498
@ -356,9 +356,13 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
|||||||
@Override
|
@Override
|
||||||
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
|
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
|
||||||
Http2Stream stream = connection.requireStream(streamId);
|
Http2Stream stream = connection.requireStream(streamId);
|
||||||
if (stream.state() == CLOSED) {
|
switch(stream.state()) {
|
||||||
// RstStream frames must be ignored for closed streams.
|
case IDLE:
|
||||||
return;
|
throw connectionError(PROTOCOL_ERROR, "RST_STREAM received for IDLE stream %d", streamId);
|
||||||
|
case CLOSED:
|
||||||
|
return; // RST_STREAM frames must be ignored for closed streams.
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.onRstStreamRead(ctx, streamId, errorCode);
|
listener.onRstStreamRead(ctx, streamId, errorCode);
|
||||||
|
@ -20,6 +20,7 @@ import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_PRIORITY_WEIGH
|
|||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.emptyPingBuf;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.emptyPingBuf;
|
||||||
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
|
||||||
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
|
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
|
||||||
|
import static io.netty.handler.codec.http2.Http2Stream.State.IDLE;
|
||||||
import static io.netty.handler.codec.http2.Http2Stream.State.OPEN;
|
import static io.netty.handler.codec.http2.Http2Stream.State.OPEN;
|
||||||
import static io.netty.handler.codec.http2.Http2Stream.State.RESERVED_REMOTE;
|
import static io.netty.handler.codec.http2.Http2Stream.State.RESERVED_REMOTE;
|
||||||
import static io.netty.util.CharsetUtil.UTF_8;
|
import static io.netty.util.CharsetUtil.UTF_8;
|
||||||
@ -501,6 +502,14 @@ public class DefaultHttp2ConnectionDecoderTest {
|
|||||||
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
|
verify(listener).onRstStreamRead(eq(ctx), eq(STREAM_ID), eq(PROTOCOL_ERROR.code()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = Http2Exception.class)
|
||||||
|
public void rstStreamOnIdleStreamShouldThrow() throws Exception {
|
||||||
|
when(stream.state()).thenReturn(IDLE);
|
||||||
|
decode().onRstStreamRead(ctx, STREAM_ID, PROTOCOL_ERROR.code());
|
||||||
|
verify(lifecycleManager).closeStream(eq(stream), eq(future));
|
||||||
|
verify(listener, never()).onRstStreamRead(any(ChannelHandlerContext.class), anyInt(), anyLong());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pingReadWithAckShouldNotifylistener() throws Exception {
|
public void pingReadWithAckShouldNotifylistener() throws Exception {
|
||||||
decode().onPingAckRead(ctx, emptyPingBuf());
|
decode().onPingAckRead(ctx, emptyPingBuf());
|
||||||
|
Loading…
Reference in New Issue
Block a user