Http2FrameCodec extends Http2ConnectionHandler { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { if (msg instanceof Http2DataFrame) { Http2DataFrame dataFrame = (Http2DataFrame) msg; encoder().writeData(ctx, dataFrame.stream().id(), dataFrame.content(), dataFrame.padding(), dataFrame.isEndStream(), promise); } else if (msg instanceof Http2HeadersFrame) { writeHeadersFrame(ctx, (Http2HeadersFrame) msg, promise); } else if (msg instanceof Http2WindowUpdateFrame) { Http2WindowUpdateFrame frame = (Http2WindowUpdateFrame) msg; writeWindowUpdate(frame.stream().id(), frame.windowSizeIncrement(), promise); } else if (msg instanceof Http2ResetFrame) { Http2ResetFrame rstFrame = (Http2ResetFrame) msg; encoder().writeRstStream(ctx, rstFrame.stream().id(), rstFrame.errorCode(), promise); } else if (msg instanceof Http2PingFrame) { Http2PingFrame frame = (Http2PingFrame) msg; encoder().writePing(ctx, frame.ack(), frame.content(), promise); } else if (msg instanceof Http2SettingsFrame) { encoder().writeSettings(ctx, ((Http2SettingsFrame) msg).settings(), promise); } else if (msg instanceof Http2GoAwayFrame) { writeGoAwayFrame(ctx, (Http2GoAwayFrame) msg, promise); } else if (!(msg instanceof Http2Frame)) { ctx.write(msg, promise); } else { ReferenceCountUtil.release(msg); throw new UnsupportedMessageTypeException(msg); } } Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings); @Override final void handlerAdded(ChannelHandlerContext ctx); @Override final void userEventTriggered(ChannelHandlerContext ctx, Object evt); @Override void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise);  }
@Test public void unknownFrameTypeShouldThrowAndBeReleased() throws Exception { class UnknownHttp2Frame extends AbstractReferenceCounted implements Http2Frame { @Override public String name() { return "UNKNOWN"; } @Override protected void deallocate() { } @Override public ReferenceCounted touch(Object hint) { return this; } } UnknownHttp2Frame frame = new UnknownHttp2Frame(); assertEquals(1, frame.refCnt()); ChannelFuture f = channel.write(frame); f.await(); assertTrue(f.isDone()); assertFalse(f.isSuccess()); assertThat(f.cause(), instanceOf(UnsupportedMessageTypeException.class)); assertEquals(0, frame.refCnt()); }
@Test public void windowUpdateFrameDecrementsConsumedBytes() throws Exception { frameListener.onHeadersRead(http2HandlerCtx, 3, request, 31, false); Http2Connection connection = frameCodec.connection(); Http2Stream stream = connection.stream(3); assertNotNull(stream); ByteBuf data = Unpooled.buffer(100).writeZero(100); frameListener.onDataRead(http2HandlerCtx, 3, data, 0, true); Http2HeadersFrame inboundHeaders = inboundHandler.readInbound(); assertNotNull(inboundHeaders); assertNotNull(inboundHeaders.stream()); Http2FrameStream stream2 = inboundHeaders.stream(); int before = connection.local().flowController().unconsumedBytes(stream); ChannelFuture f = channel.write(new DefaultHttp2WindowUpdateFrame(100).stream(stream2)); int after = connection.local().flowController().unconsumedBytes(stream); assertEquals(100, before - after); assertTrue(f.isSuccess()); data.release(); }
@Test public void windowUpdateMayFail() throws Exception { frameListener.onHeadersRead(http2HandlerCtx, 3, request, 31, false); Http2Connection connection = frameCodec.connection(); Http2Stream stream = connection.stream(3); assertNotNull(stream); Http2HeadersFrame inboundHeaders = inboundHandler.readInbound(); assertNotNull(inboundHeaders); Http2FrameStream stream2 = inboundHeaders.stream(); ChannelFuture f = channel.write(new DefaultHttp2WindowUpdateFrame(100).stream(stream2)); assertTrue(f.isDone()); assertFalse(f.isSuccess()); assertThat(f.cause(), instanceOf(Http2Exception.class)); }
@Test public void streamZeroWindowUpdateIncrementsConnectionWindow() throws Exception { Http2Connection connection = frameCodec.connection(); Http2LocalFlowController localFlow = connection.local().flowController(); int initialWindowSizeBefore = localFlow.initialWindowSize(); int windowUpdate = 1024; channel.write(new DefaultHttp2WindowUpdateFrame(windowUpdate).stream(CONNECTION_STREAM)); assertEquals(initialWindowSizeBefore + windowUpdate, localFlow.initialWindowSize()); }
@Test public void sendSettingsFrame() { Http2Settings settings = new Http2Settings(); channel.write(new DefaultHttp2SettingsFrame(settings)); verify(frameWriter).writeSettings(eq(http2HandlerCtx), same(settings), any(ChannelPromise.class)); }