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 ed51306750..a1458ad6f1 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 @@ -21,21 +21,20 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandler; import io.netty.channel.ChannelPromise; +import io.netty.handler.codec.UnsupportedMessageTypeException; +import io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeEvent; import io.netty.handler.codec.http2.Http2Connection.PropertyKey; import io.netty.handler.codec.http2.Http2Stream.State; import io.netty.handler.codec.http2.StreamBufferingEncoder.Http2ChannelClosedException; import io.netty.handler.codec.http2.StreamBufferingEncoder.Http2GoAwayException; -import io.netty.handler.codec.UnsupportedMessageTypeException; -import io.netty.handler.codec.http.HttpServerUpgradeHandler.UpgradeEvent; import io.netty.util.ReferenceCountUtil; - import io.netty.util.ReferenceCounted; import io.netty.util.internal.UnstableApi; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; -import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid; import static io.netty.handler.codec.http2.Http2CodecUtil.HTTP_UPGRADE_STREAM_ID; +import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid; /** *
This API is very immature. The Http2Connection-based API is currently preferred over this API. @@ -274,7 +273,19 @@ public class Http2FrameCodec extends Http2ConnectionHandler { writeHeadersFrame(ctx, (Http2HeadersFrame) msg, promise); } else if (msg instanceof Http2WindowUpdateFrame) { Http2WindowUpdateFrame frame = (Http2WindowUpdateFrame) msg; - writeWindowUpdate(frame.stream().id(), frame.windowSizeIncrement(), promise); + Http2FrameStream frameStream = frame.stream(); + // It is legit to send a WINDOW_UPDATE frame for the connection stream. The parent channel doesn't attempt + // to set the Http2FrameStream so we assume if it is null the WINDOW_UPDATE is for the connection stream. + try { + if (frameStream == null) { + increaseInitialConnectionWindow(frame.windowSizeIncrement()); + } else { + consumeBytes(frameStream.id(), frame.windowSizeIncrement()); + } + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } } else if (msg instanceof Http2ResetFrame) { Http2ResetFrame rstFrame = (Http2ResetFrame) msg; encoder().writeRstStream(ctx, rstFrame.stream().id(), rstFrame.errorCode(), promise); @@ -293,19 +304,6 @@ public class Http2FrameCodec extends Http2ConnectionHandler { } } - private void writeWindowUpdate(int streamId, int bytes, ChannelPromise promise) { - try { - if (streamId == 0) { - increaseInitialConnectionWindow(bytes); - } else { - consumeBytes(streamId, bytes); - } - promise.setSuccess(); - } catch (Throwable t) { - promise.setFailure(t); - } - } - private void increaseInitialConnectionWindow(int deltaBytes) throws Http2Exception { Http2LocalFlowController localFlow = connection().local().flowController(); int targetConnectionWindow = localFlow.initialWindowSize() + deltaBytes; diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameStream.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameStream.java index e417165f14..13f8634e1c 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameStream.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameStream.java @@ -24,23 +24,6 @@ import io.netty.util.internal.UnstableApi; */ @UnstableApi public interface Http2FrameStream { - - /** - * The stream with identifier 0, representing the HTTP/2 connection. - */ - Http2FrameStream CONNECTION_STREAM = new Http2FrameStream() { - - @Override - public int id() { - return 0; - } - - @Override - public State state() { - return State.IDLE; - } - }; - /** * Returns the stream identifier. * diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrame.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrame.java index b17e95dc2d..14262d12d9 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrame.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamFrame.java @@ -20,8 +20,7 @@ import io.netty.util.internal.UnstableApi; /** * A frame whose meaning may apply to a particular stream, instead of the entire connection. It is still * possible for this frame type to apply to the entire connection. In such cases, the {@link #stream()} must return - * {@link Http2FrameStream#CONNECTION_STREAM}. If the frame applies to a stream, the {@link Http2FrameStream#id()} must - * be greater than zero. + * {@code null}. If the frame applies to a stream, the {@link Http2FrameStream#id()} must be greater than zero. */ @UnstableApi public interface Http2StreamFrame extends Http2Frame { 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 7a34cfddee..e3a816c0dd 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 @@ -57,10 +57,25 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import static io.netty.handler.codec.http2.Http2CodecUtil.isStreamIdValid; -import static io.netty.handler.codec.http2.Http2FrameStream.CONNECTION_STREAM; import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.anyShort; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.same; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; /** * Unit tests for {@link Http2FrameCodec}. @@ -470,7 +485,7 @@ public class Http2FrameCodecTest { int windowUpdate = 1024; - channel.write(new DefaultHttp2WindowUpdateFrame(windowUpdate).stream(CONNECTION_STREAM)); + channel.write(new DefaultHttp2WindowUpdateFrame(windowUpdate)); assertEquals(initialWindowSizeBefore + windowUpdate, localFlow.initialWindowSize()); }