Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

@mog422
Copy link
Contributor

@mog422 mog422 commented Sep 11, 2017

A web server such as nginx assumes that upstream is dead
if upstream closes the socket without any response.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

http

@mog422 mog422 force-pushed the mog422:http.send400.on.parser.error branch 2 times, most recently Sep 11, 2017
@mscdex
Copy link
Contributor

@mscdex mscdex commented Sep 11, 2017

-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.

@mog422 mog422 force-pushed the mog422:http.send400.on.parser.error branch Sep 11, 2017
@mog422
Copy link
Contributor Author

@mog422 mog422 commented Sep 11, 2017

I clearly think that this should be done in the framework.
I have never seen user need to implement this in any framework I know.

@apapirovski
Copy link
Member

@apapirovski apapirovski commented Sep 11, 2017

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.

@jasnell
Copy link
Member

@jasnell jasnell commented Sep 12, 2017

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.

@BridgeAR
Copy link
Member

@BridgeAR BridgeAR commented Sep 13, 2017

@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.

@jasnell
Copy link
Member

@jasnell jasnell commented Sep 14, 2017

I would be extremely surprised if anything in CITGM would exercise this case so I'm not sure if that would help.

@apapirovski
Copy link
Member

@apapirovski apapirovski commented Sep 14, 2017

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?

@jasnell
Copy link
Member

@jasnell jasnell commented Sep 15, 2017

@nodejs/tsc thoughts?

@dougwilson
Copy link
Member

@dougwilson dougwilson commented Sep 15, 2017

I think this should, one day, be the default behavior when there is no registered listener. No one will really notice.

@mcollina
Copy link
Member

@mcollina mcollina commented Sep 18, 2017

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.

@jasnell
Copy link
Member

@jasnell jasnell commented Sep 19, 2017

Ok, I'm convinced ;-) ...

@dougwilson
Copy link
Member

@dougwilson dougwilson commented Sep 19, 2017

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');

This comment has been minimized.

@BridgeAR

BridgeAR Sep 19, 2017
Member

It would be nice to change this to a static value instead of using string concatenation as @mscdex pointed out.

@mog422 mog422 force-pushed the mog422:http.send400.on.parser.error branch 2 times, most recently Sep 19, 2017
@mog422
Copy link
Contributor Author

@mog422 mog422 commented Sep 19, 2017

I fixed it.

test/parallel/test-http-blank-header.js Outdated
@@ -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());

This comment has been minimized.

@cjihrig

cjihrig Sep 20, 2017
Contributor

You should probably accumulate the data in a string here and then perform the assertion in the 'end' handler.

@mog422 mog422 force-pushed the mog422:http.send400.on.parser.error branch Sep 20, 2017
@mog422
Copy link
Contributor Author

@mog422 mog422 commented Sep 20, 2017

@cjihrig fixed.

Copy link
Contributor

@cjihrig cjihrig left a comment

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).

Copy link
Contributor

@mscdex mscdex left a comment

Making it more explicit

@jasnell jasnell added the tsc-review label Sep 20, 2017
@jasnell
Copy link
Member

@jasnell jasnell commented Sep 20, 2017

Marking for tsc-review given the objections. Ping @nodejs/tsc

@jasnell jasnell requested a review from nodejs/tsc Sep 20, 2017
@Trott
Copy link
Member

@Trott Trott commented Oct 18, 2017

11 TSC members have approved. At the TSC meeting today, we agreed to take that as a vote count, so this can land.

Copy link
Contributor

@ofrobots ofrobots left a comment

+1 on the change landing. Didn't review the code.

@jasnell jasnell added this to the 9.0.0 milestone Oct 18, 2017
@addaleax
Copy link
Member

@addaleax addaleax commented Oct 18, 2017

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.

@BridgeAR
Copy link
Member

@BridgeAR BridgeAR commented Oct 19, 2017

@BridgeAR BridgeAR dismissed mscdex’s stale review Oct 19, 2017

Dismissing the blocking review due to the TSC vote.

@mcollina
Copy link
Member

@mcollina mcollina commented Oct 19, 2017

CI again: https://ci.nodejs.org/job/node-test-pull-request/10851/

It seemed very red for some infra problem.

@addaleax
Copy link
Member

@addaleax addaleax commented Oct 19, 2017

I looked through the the CI runs, nothing in there is related to this PR.

Landed in f2f391e

@addaleax addaleax closed this Oct 19, 2017
addaleax added a commit that referenced this pull request Oct 19, 2017
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>
addaleax added a commit to ayojs/ayo that referenced this pull request Oct 26, 2017
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>
addaleax added a commit to ayojs/ayo that referenced this pull request Dec 7, 2017
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>
@lpinca lpinca mentioned this pull request Feb 20, 2018
3 of 3 tasks complete
lpinca added a commit to lpinca/node that referenced this pull request Feb 20, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

Refs: nodejs#15324
benjamingr pushed a commit that referenced this pull request Feb 23, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

PR-URL: #18885
Refs: #15324
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
addaleax added a commit to addaleax/node that referenced this pull request Feb 26, 2018
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>
addaleax added a commit that referenced this pull request Feb 26, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

PR-URL: #18885
Refs: #15324
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
MayaLekova added a commit to MayaLekova/node that referenced this pull request May 8, 2018
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>
MylesBorins added a commit that referenced this pull request Aug 8, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

PR-URL: #18885
Refs: #15324
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
MylesBorins added a commit that referenced this pull request Aug 9, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

PR-URL: #18885
Refs: #15324
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
MylesBorins added a commit that referenced this pull request Aug 16, 2018
Default behavior is to send a '400 Bad Request' response if the socket
is writable.

PR-URL: #18885
Refs: #15324
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
@dougwilson dougwilson mentioned this pull request Jul 21, 2020
4 of 4 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.