Repository: netty/netty
Issue: Make it possible to specify initial settings for Http2Codec
Labels: improvement

Currently, when instantiating an Http2Codec, there does not appear to be any way of specifying non default initial settings.


Issue comments:
@nhnFreespirit so just to ensure I understand you right you suggest that we should for example allow to pass it in into the constructor ?

Yeah, having it in  a constructor of Http2Codec would solve my issues nicely.

When constructing an http/2 client, it is possible to specify non default initial settings by subclassing AbstractHttp2ConnectionHandlerBuilder and invoking the initialSettings method, but unless I am missing something, there is no reasonable way to accomplish the same when using Http2Codec to build an http/2 server.

I have a version of Netty with this added.

Only problem is I don't really like it, as to keep the initial settings optional, I have to add 2 new constructors to Http2Codec, so hesitant to create a pull request for this.

created https://github.com/netty/netty/pull/5991

Fixed by https://github.com/netty/netty/pull/5991#issuecomment-259270529


Pull request review comments:

Patch that resolved the issue:
diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Codec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Codec.java
index a61428d96d8..6a6ee39cc36 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Codec.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2Codec.java
@@ -44,6 +44,19 @@ public Http2Codec(boolean server, ChannelHandler streamHandler) {
         this(server, new Http2StreamChannelBootstrap().handler(streamHandler), HTTP2_FRAME_LOGGER);
     }
 
+    /**
+     * Construct a new handler whose child channels run in the same event loop as this handler.
+     *
+     * @param server {@code true} this is a server
+     * @param streamHandler the handler added to channels for remotely-created streams. It must be
+     *     {@link ChannelHandler.Sharable}. {@code null} if the event loop from the parent channel should be used.
+     * @param initialSettings non default initial settings to send to peer
+     */
+    public Http2Codec(boolean server, ChannelHandler streamHandler, Http2Settings initialSettings) {
+        this(server, new Http2StreamChannelBootstrap().handler(streamHandler), HTTP2_FRAME_LOGGER,
+            initialSettings);
+    }
+
     /**
      * Construct a new handler whose child channels run in a different event loop.
      *
@@ -51,13 +64,25 @@ public Http2Codec(boolean server, ChannelHandler streamHandler) {
      * @param bootstrap bootstrap used to instantiate child channels for remotely-created streams.
      */
     public Http2Codec(boolean server, Http2StreamChannelBootstrap bootstrap, Http2FrameLogger frameLogger) {
-        this(server, bootstrap, new DefaultHttp2FrameWriter(), frameLogger);
+        this(server, bootstrap, new DefaultHttp2FrameWriter(), frameLogger, new Http2Settings());
+    }
+
+    /**
+     * Construct a new handler whose child channels run in a different event loop.
+     *
+     * @param server {@code true} this is a server
+     * @param bootstrap bootstrap used to instantiate child channels for remotely-created streams.
+     * @param initialSettings non default initial settings to send to peer
+     */
+    public Http2Codec(boolean server, Http2StreamChannelBootstrap bootstrap, Http2FrameLogger frameLogger,
+                      Http2Settings initialSettings) {
+        this(server, bootstrap, new DefaultHttp2FrameWriter(), frameLogger, initialSettings);
     }
 
     // Visible for testing
     Http2Codec(boolean server, Http2StreamChannelBootstrap bootstrap, Http2FrameWriter frameWriter,
-               Http2FrameLogger frameLogger) {
-        frameCodec = new Http2FrameCodec(server, frameWriter, frameLogger);
+               Http2FrameLogger frameLogger, Http2Settings initialSettings) {
+        frameCodec = new Http2FrameCodec(server, frameWriter, frameLogger, initialSettings);
         multiplexCodec = new Http2MultiplexCodec(server, bootstrap);
     }
 
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 2a941866f6c..a9f2f725efc 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
@@ -127,11 +127,12 @@ public Http2FrameCodec(boolean server) {
      * @param server {@code true} this is a server
      */
     public Http2FrameCodec(boolean server, Http2FrameLogger frameLogger) {
-        this(server, new DefaultHttp2FrameWriter(), frameLogger);
+        this(server, new DefaultHttp2FrameWriter(), frameLogger, new Http2Settings());
     }
 
     // Visible for testing
-    Http2FrameCodec(boolean server, Http2FrameWriter frameWriter, Http2FrameLogger frameLogger) {
+    Http2FrameCodec(boolean server, Http2FrameWriter frameWriter, Http2FrameLogger frameLogger,
+                    Http2Settings initialSettings) {
         Http2Connection connection = new DefaultHttp2Connection(server);
         frameWriter = new Http2OutboundFrameLogger(frameWriter, frameLogger);
         Http2ConnectionEncoder encoder = new DefaultHttp2ConnectionEncoder(connection, frameWriter);
@@ -139,7 +140,7 @@ public Http2FrameCodec(boolean server, Http2FrameLogger frameLogger) {
         Http2FrameReader reader = new Http2InboundFrameLogger(frameReader, frameLogger);
         Http2ConnectionDecoder decoder = new DefaultHttp2ConnectionDecoder(connection, encoder, reader);
         decoder.frameListener(new FrameListener());
-        http2Handler = new InternalHttp2ConnectionHandler(decoder, encoder, new Http2Settings());
+        http2Handler = new InternalHttp2ConnectionHandler(decoder, encoder, initialSettings);
         http2Handler.connection().addListener(new ConnectionListener());
         this.server = server;
     }


Test patch:
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 260227690ca..d798d22eff4 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
@@ -70,7 +70,8 @@ public class Http2FrameCodecTest {
     @Before
     public void setUp() throws Exception {
         frameWriter = spy(new VerifiableHttp2FrameWriter());
-        framingCodec = new Http2FrameCodec(true, frameWriter, new Http2FrameLogger(LogLevel.TRACE));
+        framingCodec = new Http2FrameCodec(true, frameWriter, new Http2FrameLogger(LogLevel.TRACE),
+                                           new Http2Settings());
         frameListener = ((DefaultHttp2ConnectionDecoder) framingCodec.connectionHandler().decoder())
                 .internalFrameListener();
         inboundHandler = new LastInboundHandler();