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
|
||||
public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
|
||||
Http2Stream stream = connection.requireStream(streamId);
|
||||
if (stream.state() == CLOSED) {
|
||||
// RstStream frames must be ignored for closed streams.
|
||||
return;
|
||||
switch(stream.state()) {
|
||||
case IDLE:
|
||||
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);
|
||||
|
@ -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.Http2Error.PROTOCOL_ERROR;
|
||||
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.RESERVED_REMOTE;
|
||||
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()));
|
||||
}
|
||||
|
||||
@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
|
||||
public void pingReadWithAckShouldNotifylistener() throws Exception {
|
||||
decode().onPingAckRead(ctx, emptyPingBuf());
|
||||
|
Loading…
Reference in New Issue
Block a user