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.
This commit is contained in:
buchgr 2016-07-14 17:16:22 +02:00 committed by Norman Maurer
parent 047f6aed28
commit 328510468c
2 changed files with 20 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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() {