-
Notifications
You must be signed in to change notification settings - Fork 40.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
server.max-http-request-header-size doesn't affect Netty server with http2 enabled #36766
Conversation
…t on Netty server with http2 enabled.
@NersesAM Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@NersesAM Thank you for signing the Contributor License Agreement! |
CONTRIBUTING file is not stating against which branch should I raise PR so I have chosen the current latest release branch. Do I need to create PRs against main, 3.0, 2.7(?) as well? |
@@ -83,25 +85,19 @@ private void customizeConnectionTimeout(NettyReactiveWebServerFactory factory, D | |||
private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) { | |||
factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> { | |||
propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()) | |||
.whenNonNull() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed these as well in this method because PropertyMapper is already initialised with .alwaysApplyingWhenNonNull()
so these are redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks but please revert those as they are unrelated.
@NersesAM No need to create additional PRs. We can apply it to the appropriate branch once we've decided the earliest branch to apply the change to, then forward-merge to newer branches. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. I've reached out to the reactor team as I don't understand why we need to configure this again when using http2.
@@ -83,25 +85,19 @@ private void customizeConnectionTimeout(NettyReactiveWebServerFactory factory, D | |||
private void customizeRequestDecoder(NettyReactiveWebServerFactory factory, PropertyMapper propertyMapper) { | |||
factory.addServerCustomizers((httpServer) -> httpServer.httpRequestDecoder((httpRequestDecoderSpec) -> { | |||
propertyMapper.from(this.serverProperties.getMaxHttpRequestHeaderSize()) | |||
.whenNonNull() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks but please revert those as they are unrelated.
@@ -122,4 +117,9 @@ private void customizeMaxKeepAliveRequests(NettyReactiveWebServerFactory factory | |||
factory.addServerCustomizers((httpServer) -> httpServer.maxKeepAliveRequests(maxKeepAliveRequests)); | |||
} | |||
|
|||
private void customizeHttp2MaxHeaderSize(NettyReactiveWebServerFactory factory, long maxHttpRequestHeaderSize) { | |||
factory.addServerCustomizers(((httpServer) -> httpServer.http2Settings( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks odd to me. This is the first HTTP2-specific setting that I can see. And it being applied regardless of http2 being enabled doesn't look right.
I wonder why using HTTP2 requires to set this setting twice as we're already taking care of that in configuring HttpRequestDecoderSpec
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http1.1 uses different netty codec. Compare this stacktrace with the one above and their settings are separate
io.netty.handler.codec.http.TooLongHttpHeaderException: HTTP header is larger than 8192 bytes.
at io.netty.handler.codec.http.HttpObjectDecoder$HeaderParser.newException(HttpObjectDecoder.java:1091)
at io.netty.handler.codec.http.HttpObjectDecoder$HeaderParser.parse(HttpObjectDecoder.java:1058)
at io.netty.handler.codec.http.HttpObjectDecoder.readHeaders(HttpObjectDecoder.java:656)
at io.netty.handler.codec.http.HttpObjectDecoder.decode(HttpObjectDecoder.java:285)
at io.netty.handler.codec.http.HttpServerCodec$HttpServerRequestDecoder.decode(HttpServerCodec.java:140)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
here is where in reactor-netty-http sets the http2 settings into netty
https://github.com/reactor/reactor-netty/blob/99800186555bf874c4a4fdf6abf3e4b2da4fe0ee/reactor-netty-http/src/main/java/reactor/netty/http/server/HttpServerConfig.java#L430C7-L430C7
Fix an issue that server.max-http-request-header-size doesn't have an effect on Netty server with http2 enabled. See gh-36766
Thank you very much! I polished your changes in this commit: dc62e5f |
Setting
server.max-http-request-header-size
doesn't work when http2 is enabled on Netty server.I have created a small repro project https://github.com/NersesAM/netty-http2-bug
Steps to reproduce:
Enabling Debug logging we can see following, at info level there are no logs printed
Same curl will work if the curl request is done with http 1.1.
This can be fixed with a custom NettyCustomizer uncomment
@Component
to validate it fixes the problem. But this is unexpected behaviour as the max header size setting should apply regardless which http protocol is used. So I suggest to fix it in Spring boot with this PR.