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

@nodejs-github-bot nodejs-github-bot added the http Issues or PRs related to the http subsystem. label Sep 11, 2017
@mog422 mog422 force-pushed the http.send400.on.parser.error branch 2 times, most recently from 5147084 to 1a7fd84 Compare September 11, 2017 02:09
@mscdex
Copy link
Contributor

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 http.send400.on.parser.error branch from 1a7fd84 to c3cbc17 Compare September 11, 2017 04:34
@mog422
Copy link
Contributor Author

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

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 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 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 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 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 commented Sep 15, 2017

@nodejs/tsc thoughts?

@jasnell
Copy link
Member

jasnell commented Sep 15, 2017

@dougwilson
Copy link
Member

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

@mcollina mcollina added the semver-major PRs that contain breaking changes and should be released in the next major version. label Sep 18, 2017
@mcollina
Copy link
Member

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 commented Sep 19, 2017

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

@dougwilson
Copy link
Member

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.

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');
Copy link
Member

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.

@mog422 mog422 force-pushed the http.send400.on.parser.error branch 2 times, most recently from f163e76 to 24325ee Compare September 19, 2017 22:51
@mog422
Copy link
Contributor Author

mog422 commented Sep 19, 2017

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());
Copy link
Contributor

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.

@mog422 mog422 force-pushed the http.send400.on.parser.error branch from 24325ee to 71e702f Compare September 20, 2017 00:15
@mog422
Copy link
Contributor Author

mog422 commented Sep 20, 2017

@cjihrig fixed.

Copy link
Contributor

@cjihrig cjihrig left a 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).

mscdex
mscdex previously requested changes Sep 20, 2017
Copy link
Contributor

@mscdex mscdex left a 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

@jasnell
Copy link
Member

jasnell commented Sep 20, 2017

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

@jasnell jasnell requested a review from a team September 20, 2017 07:40
@Trott
Copy link
Member

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.

@Trott Trott removed tsc-agenda Issues and PRs to discuss during the meetings of the TSC. tsc-review labels Oct 18, 2017
Copy link
Contributor

@ofrobots ofrobots left a 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.

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

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

The CI is very red. Rerun https://ci.nodejs.org/job/node-test-pull-request/10846/

@BridgeAR BridgeAR dismissed mscdex’s stale review October 19, 2017 05:35

Dismissing the blocking review due to the TSC vote.

@mcollina
Copy link
Member

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 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 pushed 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 pushed 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 pushed 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 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 pushed 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 pushed 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 pushed 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 pushed 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 pushed 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 pushed 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.