diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java index 23769cfc9a..b9cd604063 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java @@ -141,8 +141,7 @@ public class Http2FrameCodec extends ChannelDuplexHandler { try { if (msg instanceof Http2WindowUpdateFrame) { Http2WindowUpdateFrame frame = (Http2WindowUpdateFrame) msg; - consumeBytes(frame.streamId(), frame.windowSizeIncrement()); - promise.setSuccess(); + consumeBytes(frame.streamId(), frame.windowSizeIncrement(), promise); } else if (msg instanceof Http2StreamFrame) { writeStreamFrame((Http2StreamFrame) msg, promise); } else if (msg instanceof Http2GoAwayFrame) { @@ -155,13 +154,14 @@ public class Http2FrameCodec extends ChannelDuplexHandler { } } - private void consumeBytes(int streamId, int bytes) { + private void consumeBytes(int streamId, int bytes, ChannelPromise promise) { try { Http2Stream stream = http2Handler.connection().stream(streamId); http2Handler.connection().local().flowController() .consumeBytes(stream, bytes); + promise.setSuccess(); } catch (Throwable t) { - exceptionCaught(ctx, t); + promise.setFailure(t); } } diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java index e404e396f0..c8fabd3004 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2FrameCodecTest.java @@ -402,9 +402,24 @@ public class Http2FrameCodecTest { frameListener.onDataRead(http2HandlerCtx, 3, releaseLater(data), 0, true); int before = connection.local().flowController().unconsumedBytes(stream); - channel.writeOutbound(new DefaultHttp2WindowUpdateFrame(100).setStreamId(stream.id())); + ChannelFuture f = channel.write(new DefaultHttp2WindowUpdateFrame(100).setStreamId(stream.id())); int after = connection.local().flowController().unconsumedBytes(stream); assertEquals(100, before - after); + assertTrue(f.isSuccess()); + } + + @Test + public void windowUpdateMayFail() throws Exception { + frameListener.onHeadersRead(http2HandlerCtx, 3, request, 31, false); + Http2Connection connection = framingCodec.connectionHandler().connection(); + Http2Stream stream = connection.stream(3); + assertNotNull(stream); + + // Fails, cause trying to return too many bytes to the flow controller + ChannelFuture f = channel.write(new DefaultHttp2WindowUpdateFrame(100).setStreamId(stream.id())); + assertTrue(f.isDone()); + assertFalse(f.isSuccess()); + assertThat(f.cause(), instanceOf(Http2Exception.class)); } private static ChannelPromise anyChannelPromise() {