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

Sending a body with a GET request using http.request cannot be received using http.server #3009

Closed
jameshartig opened this issue Sep 22, 2015 · 12 comments
Labels
http Issues or PRs related to the http subsystem.

Comments

@jameshartig
Copy link
Contributor

When you send a GET request using http.request to a Node.js server using the built-in http server, the parser throws an error:

HTTP 14997: parse error
NET 14997: destroy { [Error: Parse Error] bytesParsed: 87, code: 'HPE_INVALID_METHOD' }

Presumably because there was no Content-Length or Transfer-Encoding header. There was neither one of those headers because the http client code sets useChunkedEncodingByDefault to false when the method is GET. The parser hits the end of the headers and then immediately starts assuming any more data is a new HTTP request instead of it possibly being the body.

If you make the request and explicitly set the Content-Length using setHeader then no parse error is thrown. The HTTP spec says:

A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests.
But as far as I can tell, only HEAD explicitly states it cannot have a body. The server is following the spec, however:
The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers.

I'm not sure what the fix is here since turning on chunked encoding for GET might make GET's slower and I also realize this is an unintended use case (or bug in user-land) but I thought I'd bring it up.

@mscdex
Copy link
Contributor

mscdex commented Sep 23, 2015

Can you provide a complete example to reproduce the issue?

@mscdex mscdex added the http Issues or PRs related to the http subsystem. label Sep 23, 2015
@Trott
Copy link
Member

Trott commented Sep 23, 2015

HPE_INVALID_METHOD means that an invalid method (like GEM or GETA rather than GET) was received. Sample code triggering the error would be immensely helpful.

@jameshartig
Copy link
Contributor Author

Here's a quick and easy reproduction case:
https://gist.github.com/fastest963/048c6108c83f46e77eaa

@Trott The reason its throwing HPE_INVALID_METHOD was mentioned originally but I'll reiterate: Since the parser didn't get a Content-Length or Transfer-Encoding it immediately ends after reading the second \r\n and then it starts assuming the next bytes are another request instead of assuming that its the body from the first request.

@Trott
Copy link
Member

Trott commented Sep 23, 2015

The reproduction code clarifies everything. Thanks for doing that.

I can definitely see a case for considering this a bug in the userland code and not in Node. But even so, I do wonder if the error message can at least be improved or clarified somehow. I'm not sure there's an easy way to do that without possibly hitting false positives, though.

@mscdex
Copy link
Contributor

mscdex commented Sep 23, 2015

IMHO this is behaving as expected.

@tflanagan
Copy link
Contributor

I know quite a few api services that accept bodies on GET requests (where clauses, etc). If I were to implement those services in nodejs, this would fail then?

@jameshartig
Copy link
Contributor Author

@tflanagan If you sent a Content-Length or Transfer-Encoding then it would still work. I mainly filed the because there's a "bug" when requesting and receiving via the default APIs in node. If you're using a non-node client and it sends one of those headers then you're fine.

@bnoordhuis
Copy link
Member

Somewhat related to nodejs/node-v0.x-archive#5767 and nodejs/node-v0.x-archive#7575.

@jasnell
Copy link
Member

jasnell commented Apr 9, 2016

From RFC7231: A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

Sending a body in a GET has always led to undefined behavior. As far as I can tell, there's no bug here. Closing but can reopen if necessary. /cc @nodejs/http

@jasnell jasnell closed this as completed Apr 9, 2016
@inakiabt
Copy link

FYI, in my case I was sending body data in a GET request without sending Content-Length.

@bnoordhuis
Copy link
Member

@pagalasoujanya Don't hijack unrelated issues.

@borisovg
Copy link

borisovg commented Nov 2, 2018

(Note: I hate having to bring this up, but it's just that I wasted a few hours today troubleshooting why an API returned a different result when I used curl vs node client.)

From RFC7231

A payload within a GET request message has no defined semantics;
   sending a payload body on a GET request might cause some existing
   implementations to reject the request.

This does not read to me as a prohibition (certainly less so than language in earlier RFC) and considering that there are major applications (e.g. Elasticsearch) that use GET with body for queries, node should add a Content-Length header on a GET request with a body.

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.
Projects
None yet
Development

No branches or pull requests

8 participants