Http2MultiplexCodec now propagates SETTINGS and GOAWAY frames in pipeline.
Motivation: Allow the observation of SETTINGS frame by other handlers in the pipeline. For my particular use case this allows me to observe the value of MAX_CONCURRENT_STREAMS for a ChannelPool abstraction that supports HTTP/2 multiplexing. Beside this also forward GOAWAY frames. Modification: Always forward SETTINGS and GOAWAY frames Result: Settings / Goaway can now be observed in the parent channel. Previously it was not possible (to my knowledge) to capture the settings when using Http2MultiplexCodec.
This commit is contained in:
parent
02b7507a62
commit
650406c0a3
@ -66,7 +66,8 @@ import static java.lang.Math.min;
|
||||
* communication, closing of the channel is delayed until any inbound queue is drained with {@link
|
||||
* Channel#read()}, which follows the default behavior of channels in Netty. Applications are
|
||||
* free to close the channel in response to such events if they don't have use for any queued
|
||||
* messages.
|
||||
* messages. Any connection level events like {@link Http2SettingsFrame} and {@link Http2GoAwayFrame}
|
||||
* will be processed internally and also propagated down the pipeline for other handlers to act on.
|
||||
*
|
||||
* <p>Outbound streams are supported via the {@link Http2StreamChannelBootstrap}.
|
||||
*
|
||||
@ -164,8 +165,10 @@ public class Http2MultiplexCodec extends Http2FrameCodec {
|
||||
// Need to be volatile as accessed from within the DefaultHttp2StreamChannel in a multi-threaded fashion.
|
||||
volatile ChannelHandlerContext ctx;
|
||||
|
||||
Http2MultiplexCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings,
|
||||
ChannelHandler inboundStreamHandler) {
|
||||
Http2MultiplexCodec(Http2ConnectionEncoder encoder,
|
||||
Http2ConnectionDecoder decoder,
|
||||
Http2Settings initialSettings,
|
||||
ChannelHandler inboundStreamHandler) {
|
||||
super(encoder, decoder, initialSettings);
|
||||
this.inboundStreamHandler = inboundStreamHandler;
|
||||
}
|
||||
@ -218,11 +221,15 @@ public class Http2MultiplexCodec extends Http2FrameCodec {
|
||||
onHttp2StreamFrame(((Http2MultiplexCodecStream) streamFrame.stream()).channel, streamFrame);
|
||||
} else if (frame instanceof Http2GoAwayFrame) {
|
||||
onHttp2GoAwayFrame(ctx, (Http2GoAwayFrame) frame);
|
||||
// Allow other handlers to act on GOAWAY frame
|
||||
ctx.fireChannelRead(frame);
|
||||
} else if (frame instanceof Http2SettingsFrame) {
|
||||
Http2Settings settings = ((Http2SettingsFrame) frame).settings();
|
||||
if (settings.initialWindowSize() != null) {
|
||||
initialOutboundStreamWindow = settings.initialWindowSize();
|
||||
}
|
||||
// Allow other handlers to act on SETTINGS frame
|
||||
ctx.fireChannelRead(frame);
|
||||
} else {
|
||||
// Send any other frames down the pipeline
|
||||
ctx.fireChannelRead(frame);
|
||||
|
@ -231,7 +231,7 @@ public class CleartextHttp2ServerUpgradeHandlerTest {
|
||||
|
||||
ByteBuf settingsFrame = settingsFrameBuf();
|
||||
|
||||
assertFalse(channel.writeInbound(settingsFrame));
|
||||
assertTrue(channel.writeInbound(settingsFrame));
|
||||
|
||||
assertEquals(1, userEvents.size());
|
||||
assertTrue(userEvents.get(0) instanceof PriorKnowledgeUpgradeEvent);
|
||||
|
@ -41,11 +41,13 @@ import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static io.netty.util.ReferenceCountUtil.release;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
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.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
@ -175,11 +177,15 @@ public class Http2MultiplexCodecTest {
|
||||
|
||||
@Test
|
||||
public void unhandledHttp2FramesShouldBePropagated() {
|
||||
Http2PingFrame decodedFrame = new DefaultHttp2PingFrame(0);
|
||||
assertThat(parentChannel.readInbound(), instanceOf(Http2SettingsFrame.class));
|
||||
|
||||
codec.onHttp2Frame(decodedFrame);
|
||||
Http2PingFrame receivedPing = parentChannel.readInbound();
|
||||
assertSame(receivedPing, decodedFrame);
|
||||
Http2PingFrame pingFrame = new DefaultHttp2PingFrame(0);
|
||||
codec.onHttp2Frame(pingFrame);
|
||||
assertSame(parentChannel.readInbound(), pingFrame);
|
||||
|
||||
DefaultHttp2GoAwayFrame goAwayFrame = new DefaultHttp2GoAwayFrame(1);
|
||||
codec.onHttp2Frame(goAwayFrame);
|
||||
assertSame(parentChannel.readInbound(), goAwayFrame);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -619,8 +625,10 @@ public class Http2MultiplexCodecTest {
|
||||
*/
|
||||
private final class TestableHttp2MultiplexCodec extends Http2MultiplexCodec {
|
||||
|
||||
public TestableHttp2MultiplexCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder,
|
||||
Http2Settings initialSettings, ChannelHandler inboundStreamHandler) {
|
||||
public TestableHttp2MultiplexCodec(Http2ConnectionEncoder encoder,
|
||||
Http2ConnectionDecoder decoder,
|
||||
Http2Settings initialSettings,
|
||||
ChannelHandler inboundStreamHandler) {
|
||||
super(encoder, decoder, initialSettings, inboundStreamHandler);
|
||||
}
|
||||
|
||||
@ -682,6 +690,7 @@ public class Http2MultiplexCodecTest {
|
||||
}
|
||||
|
||||
private final class TestableHttp2MultiplexCodecBuilder extends Http2MultiplexCodecBuilder {
|
||||
|
||||
TestableHttp2MultiplexCodecBuilder(boolean server, ChannelHandler childHandler) {
|
||||
super(server, childHandler);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user