-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Micronaut server is not working for clear text http2 (h2c) #5005
Comments
Please let me know if I should provide any further information for the issue. |
Relates to #3389 Since browsers don't event support h2c currently Micronaut only supports h2 with HTTPS enabled. There are actually issues with the underlying Netty APIs that prevent us from fully supporting h2c |
I see :( Do you know the issue number on the Netty side, I have searched it but couldn't find it. |
@graemerocher wrote:
True regarding browser support, but I assume many Micronaut users are building for machine-to-machine use cases where a browser is never involved. That's my use case anyway, and I'd like to get HTTP/2's compact wire format and connection reuse without being required to use TLS.
Could you elaborate? I researched this a bit today in the Netty repo, and I gather that folks are able to use Netty+h2c successfully elsewhere. Like the OP, I didn't see anything regarding "issues with [...] Netty APIs that prevent [...] fully supporting h2c" For context, I'm vetting Micronaut for its suitability in implementing a certain system. h2c may end up being a hard requirement in that system, and I'd like to get a sense of how feasible it would be to implement that support ourselves if need be, i.e. to fix whatever needs fixing in Netty, etc. Thanks. |
Hi Chris! Nice hearing from you, hope everything is well on your end. The issue is the same as this one with Spring spring-projects/spring-boot#19460 which points back to netty/netty#7079 Having said that it is a while since we looked this and maybe the underlying Netty APIs have evolved / been fixed so probably worth having another debugging session. |
@yawkat next time you have cycles please take a crack at resolving this Netty issue |
Thanks, @graemerocher (and thanks in advance, @yawkat)! Regarding the linked Spring and Netty issues, they talk about issues completing an h2c upgrade where a request has a body, e.g. a POST, and that such an issue on the Netty side can be solved through configuration. In my case, though, I see the reported behavior when there is neither an upgrade request nor a request body involved. Here are the relevant bits from my micronaut:
application:
name: repro
server:
port: 2040
http-version: 2.0 For a baseline, let's observe that a vanilla HTTP/1.1 GET request works just fine:
Now let's try the same GET request via HTTP/2, bypassing any upgrade negotiation with curl's
|
#5005] From NettyServerUpgradeHandler: "The upgrade was successful, remove the message from the output list so that it's not propagated to the next handler. This request will be propagated as a user event instead." So, the first request is discarded. This patch sends it downstream for normal handling.
#5005] From NettyServerUpgradeHandler: "The upgrade was successful, remove the message from the output list so that it's not propagated to the next handler. This request will be propagated as a user event instead." So, the first request is discarded. This patch sends it downstream for normal handling.
…er [Fixes #5005] (#6270) Before this patch, the h2c server would not respond to the initial request that started the h2c upgrade, and the client would improperly handle the response to its own upgrade request. This patch changes the server to respond to the first request, and the client to ignore messages on h2c stream 1 (the stream the response arrives on), to make them compatible with the spec. This means that old micronaut h2c clients without this patch are now incompatible with fixed h2c servers.
This particular bug should be fixed now, but there are still outstanding issues with the h2c support. |
Great, @yawkat, thanks! Looking forward to trying out the snapshot.
Could you elaborate? Is it reasonable to expect that many/most typical use cases should work under |
One issue I found is #6282. The h2c implementation (by necessity) has some pretty special properties because of the upgrade mechanism required, and this is leading to downstream issues like this. It is also not well-tested right now. We discussed this internally and with potential changes on the standards and netty side of things h2c isn't really something to recommend. It is better to stick to normal http2. Finally, the support for http2 in general is lacking on the feature side, e.g. the client connection pooling isn't ideal. |
I just tried out the fix, and the good news is that http2 over cleartext (h2c) now works as expected, e.g.:
However, it works if and only if there is an upgrade request involved, as there was in the example above. If, alternatively, I make the equivalent request directly via HTTP/2 (see the
|
Just to clarify, "normal http2" above is referring to Given this constraint, it does indeed make sense in most cases to recommend that folks stay away from h2c and go with h2. I'd like to make the case, though, why it's still worth providing first-class support for h2c in Micronaut. The first reason is for local network development use cases, where setting up self-signed certs, etc is just painful overhead. The second reason is more specific to my application, though not necessarily unique to it. In my application, there are potentially many Micronaut instances in constant peer-to-peer communication with each other. This p2p communication happens via HTTP over Tor, where each Micronaut instance is a Tor onion service (aka Tor hidden service). As explained at https://security.stackexchange.com/a/75984, using TLS when communicating with Tor onion services is redundant, inefficient and harmful to privacy. So TLS is really not wanted here, but HTTP/2's tight wire format and long-lived connections very much are! Particularly in a Tor environment, where establishing individual connections is extra expensive, having long-lived connections makes it feasible to pass lots of messages over HTTP. Without HTTP/2's connection reuse, one would probably have to drop down to building a custom protocol on top of raw sockets. Similarly, HTTP/2's header compression and binary wire format makes it feasible to pass around lots of HTTP messages efficiently. Without it, one would probably have to use e.g. protobufs or create a bespoke binary wire format. Being able to do all of these once custom, low-level things in plain-old-HTTP is hugely beneficial to developer productivity, system understandability, and implementation interoperability. Again, I realize this use case is probably far from the norm for most Micronaut users, but I hope this context helps make it clear why using h2c in production can actually be a critical requirement. Thanks. |
I have created a separate issue for prior knowledge support. I don't really see that the disadvantage of having to deal with self-signed certificates outweighs the security (even if it may seem superfluous in some cases) and simplicity advantage that TLS-based http2 has. I can see the privacy issues in your particular use case though. One solution would be to use a single certificate for all peers. There would still be some level of transport security because of TLS forward secrecy. Either way, HTTP3 will not support an unencrypted mode from what I understand, and I don't know about the netty 5 support either. So I would avoid relying on h2c as a standard. |
I am trying to use h2c protocol on the Micronaut however my endpoint is not responding the request when I use http2. This is my configuration for the h2c
Task List
Steps to Reproduce
Use the sample application from https://github.com/umutkocasarac/micronaut-h2c-test and run the application with ./gradlew run then make a curl request to the application
or this one
Expected Behaviour
It should upgrade the protocol to http2 and then respond the client
Actual Behaviour
Application freezes after the following log
Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
Environment Information
Example Application
https://github.com/umutkocasarac/micronaut-h2c-test
The text was updated successfully, but these errors were encountered: