Drop unknown frames on connection stream (#10771)

Motivation:

We received a [bug report](https://bugs.chromium.org/p/chromium/issues/detail?id=1143320) from the Chrome team at Google, their canary builds are failing [HTTP/2 GREASE](https://tools.ietf.org/html/draft-bishop-httpbis-grease-00) testing to netflix.com.

The reason it's failing is that Netty can't handle unknown frames without an active stream created. Let me know if you'd like more info, such as stack traces or repro steps. 

Modification:

The change is minor and simply ignores unknown frames on the connection stream, similarly to `onWindowUpdateRead`.

Result:

I figured I would just submit a PR rather than filing an issue, but let me know if you want me to do that for tracking purposes.
This commit is contained in:
Arthur Gonigberg 2020-11-04 05:01:08 -08:00 committed by Norman Maurer
parent 6af982b1e5
commit f053870f38
2 changed files with 16 additions and 0 deletions

View File

@ -532,6 +532,10 @@ public class Http2FrameCodec extends Http2ConnectionHandler {
@Override @Override
public void onUnknownFrame( public void onUnknownFrame(
ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags, ByteBuf payload) { ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags, ByteBuf payload) {
if (streamId == 0) {
// Ignore unknown frames on connection stream, for example: HTTP/2 GREASE testing
return;
}
onHttp2Frame(ctx, new DefaultHttp2UnknownFrame(frameType, flags, payload) onHttp2Frame(ctx, new DefaultHttp2UnknownFrame(frameType, flags, payload)
.stream(requireStream(streamId)).retain()); .stream(requireStream(streamId)).retain());
} }

View File

@ -389,6 +389,18 @@ public class Http2FrameCodecTest {
assertEquals(0, frame.refCnt()); assertEquals(0, frame.refCnt());
} }
@Test
public void unknownFrameTypeOnConnectionStream() throws Exception {
// handle the case where unknown frames are sent before a stream is created,
// for example: HTTP/2 GREASE testing
ByteBuf debugData = bb("debug");
frameInboundWriter.writeInboundFrame((byte) 0xb, 0, new Http2Flags(), debugData);
channel.flush();
assertEquals(0, debugData.refCnt());
assertTrue(channel.isActive());
}
@Test @Test
public void goAwayLastStreamIdOverflowed() throws Exception { public void goAwayLastStreamIdOverflowed() throws Exception {
frameInboundWriter.writeInboundHeaders(5, request, 31, false); frameInboundWriter.writeInboundHeaders(5, request, 31, false);