From 328510468c3da0f6a37d9710d7723f817eff8ce8 Mon Sep 17 00:00:00 2001 From: buchgr Date: Thu, 14 Jul 2016 17:16:22 +0200 Subject: [PATCH] Complete ChannelPromise for Http2WindowUpdateFrames in Http2FrameCodec. Fixes #5530 Motivation: The channel promise of a window update frame is not completed correctly, depending on the failure or success of the operation. Modification: Succeed / Fail the promise if the window update succeeds / fails. Result: Correctly succeed / fail the promise. --- .../handler/codec/http2/Http2FrameCodec.java | 8 ++++---- .../codec/http2/Http2FrameCodecTest.java | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) 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() {