micronaut-core
micronaut-core copied to clipboard
Netty HttpClient times out when sending a request body longer than 8096 bytes to an HTTP/2 endpoint
Expected Behavior
From a Netty DefaultHttpClient user's perspective, sending a request to an HTTP/2 endpoint should work for any content length so long as its under the threshold at which the server returns 413 Content Too Large.
This was working previously working for me on micronaut-core 4.6.6.
Actual Behaviour
When sending a request with more than 8096 bytes, evidently a threshold defined in Netty's HttpPostBodyUtil, to an HTTP/2 webserver, I eventually encounter either a ReadTimeout or ResponseClosedException as a result of the server unceremoniously closing the client's connection.
Stepping into the code a bit more deeply, I noticed that execution is winding up hitting this error, though it isn't really surfaced in logs:
Message must be an Http2StreamFrame: UnpooledSlicedByteBuf(ridx: 0, widx: 8096, cap: 8096/8096, unwrapped: CompositeByteBuf(ridx: 0, widx: 8096, cap: 8096, components=2))
https://github.com/netty/netty/blob/netty-4.1.114.Final/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2StreamChannel.java#L1007
I'm not 100% sure, but I think this might be a regression from https://github.com/micronaut-projects/micronaut-core/pull/11158.
Steps To Reproduce
I created this test case reproducing the issue: https://github.com/micronaut-projects/micronaut-core/compare/4.7.x...asw12:micronaut-core:large-http2-request#diff-64c535267c745f508c54cda504f9faccdb75b71c7877019c2851de2a8dac7a2aR36
It's basically a copy of the existing JDK Http2Spec.groovy, but in the netty client module.
+ def "test http2 post long string"() {
+ when:
+ def body = Map.of("q", "a" * 8097)
+
+ def response = client.toBlocking().retrieve(HttpRequest.POST("/http2", body)
+ .contentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE))
+
+ then:
+ response == "hello"
+ }
+
+
@Controller("/http2")
@Requires(property = "spec.name", value = "Http2Spec")
static class SpecController {
@Get
@Produces(MediaType.TEXT_PLAIN)
String get() {
"hello"
}
+
+ @Post
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ @Produces(MediaType.TEXT_PLAIN)
+ String post() {
+ "hello"
+ }
}
Environment Information
JDK Version 17
Example Application
https://github.com/asw12/micronaut-core/tree/large-http2-request
Version
micronaut-core 4.7.0
I'll take a look at the test case. Can you sign the CLA so I can use your test case if I make a PR? https://cla-assistant.io/micronaut-projects/micronaut-core