-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
http: relax requirements on upgrade listener #19981
Conversation
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.
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.
SGTM
Can you please run CIGTM? |
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.
LGTM with some minor nits.
@@ -530,14 +530,14 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { | |||
parser = null; | |||
|
|||
var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; | |||
if (server.listenerCount(eventName) > 0) { | |||
if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) { |
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.
can you combine this if with the ternary before somehow? With this change we truly only need to do server.listenerCount('connect')
here.
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.
I don't think we can combine it with the ternary since the eventName
is also used inside the if clause when emitting. We could change server.listenerCount(eventName)
to be server.listenerCount('connect')
but I'm not sure that's truly better... I suppose a bit more descriptive?
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.
As I said, I'm not convinced. Removing the ternary might create code that is harder to read in the end.
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.
@mcollina ... are you ok with this landing without this change?
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.
To be clear, I would be happy to make a change but I'm not sure what it would be. I don't think there's a way to simplify this since eventName
is used inside the body of the if statement.
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.
The only thing I can think of is reversing the condition but it doesn't change anything.
if (eventName === 'connect' && server.listenerCount('connect') === 0) {
socket.destroy();
} else {
// ...
}
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.
Yes definitely.
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 can land
lib/_http_client.js
Outdated
@@ -492,6 +492,9 @@ function parserOnIncomingClient(res, shouldKeepAlive) { | |||
} | |||
req.res = res; | |||
|
|||
if (res.upgrade) | |||
return 2; |
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.
Can you please add the comment:
// Skip body and treat as Upgrade.
It was there in _http_common.js
test_upgrade_no_listener_ended = true; | ||
conn.once('data', (data) => { | ||
assert.strictEqual('string', typeof data); | ||
assert.strictEqual('HTTP/1.1 200', data.substr(0, 12)); |
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.
Nit: please switch the arguments order to adhere to actual, expected
.
CI before landing https://ci.nodejs.org/job/node-test-pull-request/14320/ |
Failure on CI is unrelated, landing. |
Landed in f7fbbee |
@jasnell can you have a look at adding this to 10? |
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>
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>
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.
Refs: https://tools.ietf.org/html/rfc7230#section-6.7
Fixes: #11552
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes