-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
node servers should handle upgrade headers gracefully #11552
Comments
I don't see anything in the linked http/1.1 spec section that says how to properly deny a connection upgrade request (from a client). It does mention "ignoring" the Upgrade header, and maybe that's badly worded, but to me that's different than ignoring a connection upgrade request which is both an Upgrade header and |
All The HTTP specs are very large, can you point where in the spec the difference between having an Upgrade header and what an "upgrade request" is? Requests with |
Once the basic http/2 implementation is done, I do plan to revisit the way upgrade is handled currently so that negotiation between http/1 and http/2 is possible. There are going to be some quirks to deal with due to differences between the APIs, but it is definitely on my radar. |
That sounds great! As we discussed on Twitter, I think it might make sense to have an intermediate step where node still can't upgrade to h2c but can at least speak HTTP/1.1 to h2c clients that send upgrade headers by default. |
I found this issue after reading the docs on upgrade.
To my understanding, what should trigger a client to react is when the server responds with:
The event should not fire, and the connection should close in both cases. What actually matters is, if the upgrade has been requested with this particular request, and whether or not the server responds with a valid My first comment on GitHub, so, hello everybody. |
@jasnell have you had a chance to revisit this? I believe node still breaks with h2c clients. |
@jasnell now that you've landed h2, can we revisit h2c? |
Can this be revisited by any chance? Even if we ignore the implementation details of h2c switching — the current http behaviour is completely against the spec.
As @dougwilson mentioned above, It seems like this would ideally be changed so that 'upgrade' is emitted but not required to be listened to (and the connection is never cut). I can't imagine much would break if this change were implemented whereas it's pretty certain that the current behaviour already breaks things. |
The RFC states regarding a client sending the Upgrade header; My suggestion for this to work both client-side and server-side in Node, is to allow http1 and http2 (or at least http1) sessions (connections) to be detachable from their socket, and leave this flow up to user code to handle, if at all. Client-side It is almost possible to convert an upgraded client-socket (after having gotten the Server-side When you get the EDIT: Maybe introduce a Care must be taken if Upgrade was in a non-GET method (is this allowed/done/possible?), where the server must first read the entire body before internally switching over to another protocol handler... |
@grantila I don't really care how this is resolved as long as the default is no longer that node hangs up if a client sends it an upgrade header. |
@mosesn the problem is, the rest of us do care |
@grantila sorry for being grumpy, I filed this ticket seven months ago to fix a specific issue I'm running into, and I've been totally unable to get anybody to agree on a fix to it. So I think your solution seems reasonable but it's not clear to me that it fixes the fundamental issue in this ticket, which is that unconfigured node servers hang up when they receive upgrade headers. |
@nodejs/http @nodejs/http2 I would like to at least discuss this before v10.x lands because this will almost certainly be semver-major and I don't want it to wait until yet another major version. |
@apapirovski To be clear, the suggestion is to ignore such a header by default? Or do we actually want to implement a transparent switch to HTTP/2 (which might be doable)? |
Also @nodejs/tsc because the deadline that we set for semver-majors in 10.0.0 without TSC confirmation has passed |
@addaleax the suggestion is to conform to the spec which says that |
I’m totally fine with ignoring the header by default, but we (you? me?) should get a PR up asap. We might also want to provide an option to fall back to the old behaviour, I guess? |
Yeah, sorry been unavailable for a while at an inconvenient time but I've had a list of these things that I think need to get into 10.x. I have a few more that I'm working on PRs for, hopefully can open today or tomorrow. |
@lpinca what do you think? @apapirovski do we have a fix for this already? If we do, we might try to fit it in before 10.0.0, but the deadline has passed already. Ideally it should be landed before next Wednesday, so that we can talk about the backport at the next TSC meeting. However, we cannot promise anything at this point. |
I think it's fine to ignore if there is no handler but I'm not sure if and how much code it will break. I guess not much. |
Ignore me. Upon another read through of the spec, looks like we're all good with |
PR in #19981 |
The http spec does not say anything about Upgrade headers making protocol switch mandatory but Node.js implements them as if they are. Relax the requirements to only destroy the socket if no upgrade listener exists on the client when status code is 101. PR-URL: #19981 Fixes: #11552 Refs: https://tools.ietf.org/html/rfc7230#section-6.7 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Today, node servers cut the connection when they receive upgrade headers, which isn't advised in the http/1.1 or http/2 specs. As http/2 gains a wider mindshare, h2c will see an uptick in adoption in intra-datacenter use, so if node wants to continue being viable in microservice architectures, it makes sense to at least play nicely with h2c clients, even if it doesn't want to implement h2c by default.
Instead, node servers should ignore the upgrade header and treat it as a normal request if the implementor hasn't defined anything special to do to it.
The text was updated successfully, but these errors were encountered: