-
-
Notifications
You must be signed in to change notification settings - Fork 935
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
Return error when content-length header does not match bytes transferred #1462
Comments
Can you make an example? |
Yeah, I'm not sure about producing a test case. Currently, I make it fail by disabling / re-enabling my wifi during a heavy download from a remote server (using node v14.10.1 on macOS 10.15.6). Looking into it, the issue does seem to be related to HTTP2 downloads, as I am unable to trigger the error with it disabled. |
I tried running with
|
I have not been able to create a test case, but I can present more details: This issue is server dependent. If I use nginx termination instead of envoy, it does not fail. I have not been able to debug the HTTP2 frames, but I have a strong feeling that this issue is caused by insufficient response validation in node. Specifically the
Further code analysis shows that nghttp2 supposedly validates the content-length, before handing over the response to node in http2/core.js. Given this, the bug is likely to be found inside nghttp2. Digging into the code, the content-length is indeed validated. However, this logic might not always be called. Specifically So the theory is that this bug will trigger on HTTP2 streams, that contain a |
@Giotino The socket is destroyed as usual, but the thing is that you cannot verify whether it was destroyed because the connection was reset or it was successful. I have experienced this a lot on Android. |
Digging into envoy, I found further evidence to the theory, as it can indeed send RST frames with |
Yup, this is an nghttp2 issue, as speculated. Though, any fix will take some time to arrive in node, so it might make sense to add a workaround here? The issue only applies to streams that have fewer bytes than the content-length indicates, so it should be able to be detected by tracking the consumed bytes, and comparing it to the content-length before finishing the stream. I'm still at a loss for a test case, since I don't know how to create a test with a server that sends RST_STREAM with error_code 0. |
I made a failing test using http2 streams here: nodejs/node#35209 (comment). I also managed to find problems when a server closes the stream with |
If you want to work around this last bug, you could check the stream |
@kanongil I am facing a similiar problem at the moment . Whenever the source file on the server is being overwritten during a download with You think this rstCode workaround could be used in my case ? And how would that work since there are no parameters given to the end event handler got.stream().on('end', (event) => {
console.log(event);
// undefined
}); |
@turbopasi It should be a property on the |
Thanks ! I just tested it real quick , but didn't have any luck : const request = got.stream('https://whatever')
.on('end', () => {
console.log(Object.keys(request));
console.log(request.rstCode); // logs undefined
}); I probably have some misunderstanding here - where should this rstCode exactly be ? 🤔 |
So the workaround was meant to be used internally in got. As a client you need to find the http2 stream to access it. |
What problem are you trying to solve?
Safely retrieve content delivered from a server.
Describe the feature
Depending on how the stream is sent from the server, got will happily complete without error, even if the actual bytes transferred does not match the value in the
content-length
header.While it is possible to workaround, and detect manually, it is quite cumbersome, especially if
decompress
is enabled.FYI, it is not a problem when the server responds with
content-encoding: chunked
, since node will error if such a stream is interrupted.Checklist
The text was updated successfully, but these errors were encountered: