From 870b5f5e4b4eef8ea3baf650fa9c592533b2fda2 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 5 Sep 2017 18:34:34 +0100 Subject: [PATCH] Not add inboundStreamHandler for outbound streams created by Http2MultiplexCodec. Motivation: We must not add the inboundStreamHandler for outbound streams creates by Http2MultiplexCodec as the user will specify a handler via Http2StreamChannelBootstrap. Modifications: - Check if the stream is for outbound and if so not add the inboundStreamHandler to the pipeline - Update tests so this is covered. Result: Fixes [#7178] --- .../handler/codec/http2/Http2MultiplexCodec.java | 14 +++++++++----- .../http2/Http2MultiplexCodecBuilderTest.java | 8 +++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java index 7cb3ec0c70..db513d3dae 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodec.java @@ -239,7 +239,7 @@ public class Http2MultiplexCodec extends Http2FrameCodec { break; } // fall-trough - DefaultHttp2StreamChannel childChannel = new DefaultHttp2StreamChannel(stream); + DefaultHttp2StreamChannel childChannel = new DefaultHttp2StreamChannel(stream, false); ChannelFuture future = ctx.channel().eventLoop().register(childChannel); if (future.isDone()) { registerDone(future); @@ -266,7 +266,7 @@ public class Http2MultiplexCodec extends Http2FrameCodec { // TODO: This is most likely not the best way to expose this, need to think more about it. final Http2StreamChannel newOutboundStream() { - return new DefaultHttp2StreamChannel(newStream()); + return new DefaultHttp2StreamChannel(newStream(), true); } @Override @@ -403,6 +403,7 @@ public class Http2MultiplexCodec extends Http2FrameCodec { private final ChannelPipeline pipeline; private final Http2FrameStream stream; private final ChannelPromise closePromise; + private final boolean outbound; private volatile boolean registered; private volatile boolean writable; @@ -427,8 +428,9 @@ public class Http2MultiplexCodec extends Http2FrameCodec { // channelReadComplete(...) DefaultHttp2StreamChannel next; - DefaultHttp2StreamChannel(Http2FrameStream stream) { + DefaultHttp2StreamChannel(Http2FrameStream stream, boolean outbound) { this.stream = stream; + this.outbound = outbound; ((Http2MultiplexCodecStream) stream).channel = this; pipeline = new DefaultChannelPipeline(this) { @Override @@ -791,8 +793,10 @@ public class Http2MultiplexCodec extends Http2FrameCodec { registered = true; - // Add the handler to the pipeline now that we are registered. - pipeline().addLast(inboundStreamHandler); + if (!outbound) { + // Add the handler to the pipeline now that we are registered. + pipeline().addLast(inboundStreamHandler); + } promise.setSuccess(); diff --git a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilderTest.java b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilderTest.java index 383d17104c..f798b021f7 100644 --- a/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilderTest.java +++ b/codec-http2/src/test/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilderTest.java @@ -32,6 +32,7 @@ import io.netty.channel.local.LocalChannel; import io.netty.channel.local.LocalServerChannel; import org.junit.After; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -82,7 +83,12 @@ public class Http2MultiplexCodecBuilderTest { Bootstrap cb = new Bootstrap() .channel(LocalChannel.class) .group(group) - .handler(new Http2MultiplexCodecBuilder(false, new TestChannelInitializer()).build()); + .handler(new Http2MultiplexCodecBuilder(false, new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + Assert.fail("Should not be called for outbound streams"); + } + }).build()); clientChannel = cb.connect(serverAddress).sync().channel(); assertTrue(serverChannelLatch.await(5, SECONDS)); }