-
Notifications
You must be signed in to change notification settings - Fork 29.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
http: send 400 bad request on parse error #15324
Conversation
5147084
to
1a7fd84
Compare
-1 I would prefer to have this explicitly done by userland. Also, this could cause some backwards compatibility issues... FWIW code-wise the response written to the socket could be a static Buffer for better performance. |
1a7fd84
to
c3cbc17
Compare
I clearly think that this should be done in the framework. |
Not sure about compatibility but it does feel weird that this is in user-land when comparing it to http2. Seems like node is potentially encouraging a lot of badly behaved servers out there. Just looking at popular user-land implementations, only fastify behaves well. |
Preferably, this would have been the behavior from the beginning, for backwards compatibility reasons now, I'd say that this is not worth changing and should be kept to userland. The http/2 implementation was intentionally made stricter in these kinds of cases to avoid having this kind of problem. I'm -1 on this change. |
@jasnell what do you think about just running CITGM on it and see how bad things break? This would be semver-major anyway and I do see the point that it makes sense to have it in the framework. Especially as a lot of servers will likely not handle this properly because they did not think about it. |
I would be extremely surprised if anything in CITGM would exercise this case so I'm not sure if that would help. |
Some of the libraries likely have tests around this behaviour, no? Feels like at the very least this would be interesting to test & see what it does with CITGM. Couldn't Node ultimately emit a warning and then semver-major release it, or something? The fact that this only affects situations where the end-users haven't bound a listener for 'clientError' should make the risk of this at least a little bit smaller, no? If they're not doing any handling of their own, is it that likely to break their code? |
@nodejs/tsc thoughts? |
I think this should, one day, be the default behavior when there is no registered listener. No one will really notice. |
This is a semver-major change. The major problem is that the top frameworks are not implementing it. I think that adding it to core it's the best solution to fix this issue. @dougwilson are you ok with this one? I'm 👍 if it's ok for you. |
Ok, I'm convinced ;-) ... |
At least for frameworks like Connect / Express / Koa they all sit abstracted higher than the server instance, so they don't have the server reference to add a listener, which is why none of those frameworks set up this kind of listener. But, if these frameworks ever wanted to, doing so would replace this default handler, so there doesn't seem like much downside to me. |
lib/_http_server.js
Outdated
if (!this.server.emit('clientError', e, this)) | ||
if (!this.server.emit('clientError', e, this)) { | ||
if (this.writable) | ||
this.write('HTTP/1.1 400 ' + STATUS_CODES[400] + CRLF + CRLF, 'ascii'); |
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.
It would be nice to change this to a static value instead of using string concatenation as @mscdex pointed out.
f163e76
to
24325ee
Compare
I fixed it. |
@@ -47,7 +47,9 @@ server.listen(0, common.mustCall(() => { | |||
'\r\n\r\nhello world' | |||
); | |||
})); | |||
|
|||
c.on('data', common.mustCall((data) => { | |||
assert.strictEqual('HTTP/1.1 400 Bad Request\r\n\r\n', data.toString()); |
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.
You should probably accumulate the data in a string here and then perform the assertion in the 'end'
handler.
24325ee
to
71e702f
Compare
@cjihrig fixed. |
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.
Code LGTM.
I do see the potential for backwards compatibility issues too though. @mscdex, you might want to use the big red X to prevent your -1 from getting accidentally overlooked (if you feel strongly enough about it).
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.
Making it more explicit
Marking for tsc-review given the objections. Ping @nodejs/tsc |
11 TSC members have approved. At the TSC meeting today, we agreed to take that as a vote count, so this can land. |
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.
+1 on the change landing. Didn't review the code.
Old CIs are inaccessible, so here’s a fresh one: https://ci.nodejs.org/job/node-test-commit/13272/ (Looks like AIX already broke down due to build system changes? @nodejs/build) This should be ready. |
The CI is very red. Rerun https://ci.nodejs.org/job/node-test-pull-request/10846/ |
Dismissing the blocking review due to the TSC vote.
CI again: https://ci.nodejs.org/job/node-test-pull-request/10851/ It seemed very red for some infra problem. |
I looked through the the CI runs, nothing in there is related to this PR. Landed in f2f391e |
A web server such as nginx assumes that upstream is dead if upstream closes the socket without any response. PR-URL: #15324 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
A web server such as nginx assumes that upstream is dead if upstream closes the socket without any response. PR-URL: nodejs/node#15324 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
A web server such as nginx assumes that upstream is dead if upstream closes the socket without any response. PR-URL: nodejs/node#15324 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Evan Lucas <evanlucas@me.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Default behavior is to send a '400 Bad Request' response if the socket is writable. Refs: nodejs#15324
Default behavior is to send a '400 Bad Request' response if the socket is writable. PR-URL: nodejs#18885 Refs: nodejs#15324 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Default behavior is to send a '400 Bad Request' response if the socket is writable. PR-URL: nodejs#18885 Refs: nodejs#15324 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
A web server such as nginx assumes that upstream is dead
if upstream closes the socket without any response.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
http