-
-
Notifications
You must be signed in to change notification settings - Fork 133
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
Requests can hang with malformed JSONs; depends on error handling #123
Comments
Hey @juona, thanks for the super detailed report. As the original author of the offending line, I figured I should hop in and confirm:
I think the first step is definitely going to be to reproduce this in a test. I'll see if I can find some time tomorrow to poke around. @juona - which version of node is this running on? |
Oh hey,
Question: I am not a very experienced software engineer, so would you be able to provide a bit of explanation of what a "broken HTTP transaction" would mean in this case and what the ramifications are? I guess in this case using |
What I mean by "broken HTTP transaction", is that the client will attempt to send its headers and the entirety of its request body along the TCP connection (this is all assuming we aren't using the HTTP 100 [Continue] flow). If we attempt to send a response and end the request/close the connection before the body has finished being sent, all browsers and all popular reverse proxies will treat this as a network failure, and the response status and body will be abandoned. While this is fine if you're trying to prevent DOS attacks, you definitely don't want this kind of behavior for a non-malicious client. There is the case where node has received the entire request body (so the client will now accept a response) even though our code hasn't actually read the entire body out of node's internal stream buffer. This is essentially why this bug exists – because I didn't test this case with a large enough payload. :( EDIT: As an addendum, this last case is something to which most node developers (even very experienced ones) are oblivious. It's really easy to just use small payloads when writing tutorials or tests, and not realize that your code's behavior can be so dramatically different with just a few more bytes of data. Likewise, it's possible to make similarly detrimental omissions if you only use a large request, such as assigning listeners after an event has occurred. This is why several of our tests in this repo use multiple request sizes... and why they all probably should. |
Thank you, the explanation makes sense : ] Come to think of it, I did notice that smaller JPEGs seemed to work differently, i.e. would sometimes return responses, but the behaviour was inconsistent and I couldn't understand what was going on, so I didn't mention it in the description. Happy to see smart people working on packages that I use - makes me feel secure ^^ |
Fix #123 - request paused on exit
The fix is published in |
Jayden,
Great work on the library, and thanks for pushing guys @ Apollo. Your workaround works well enough so that I wouldn't care about them fixing their own dependency.
I am now using [email protected] with Express and have found this one rather small issue.
In the express middleware you have written code which (please correct me if I am wrong) is meant to delay the final response until the upload has ended:
https://github.com/jaydenseric/graphql-upload/blob/master/src/graphqlUploadExpress.mjs#L36
https://github.com/jaydenseric/graphql-upload/blob/master/src/graphqlUploadExpress.mjs#L32.
The issue is that the
finished
promise is listening forrequest.on("end")
, which apparently doesn't happen if an error occurs while uploading. Scenario is this:operations
JSON).request.send
(or.json
- it resolves to.send
). E.g. I have this little piece:When
.json()
is called, the flow goes to your middleware:https://github.com/jaydenseric/graphql-upload/blob/master/src/graphqlUploadExpress.mjs#L36
However, in this scenario the
end
event is never fired on therequest
. Two workarounds are available:response.end()
instead of.send()
or.json()
. I'd like to stick with.json
, however.end
event in case of an error:request.emit("end")
.Questions to you:
end
event is not firing in case of an error in the upload middleware?end
manually seem like a good fix which can be applied now?The text was updated successfully, but these errors were encountered: