-
Notifications
You must be signed in to change notification settings - Fork 582
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
Response body ends prematurely #803
Comments
@dnlup would you mind taking a look and maybe making a test? |
How does Node.js handle this case? |
It just works. This might be a wasm thing. |
Are we talking about something greater than |
No, I have a case where I'm unable to receive anything larger than ~2^31. I'm not sure if it's undici at the moment but I think it's good idea to have a test where we transfer more than 2^32 bytes. |
Could also be a problem with Node 16 http1/http2 server. I'm seeing the issue in a reverse proxy in production. |
Inspecting |
I think the problem is with Node. It happens only if you pass the entire buffer to I used Node 16 to test. |
Something is weird. undici always prematurely ends response at 1605405800 bytes without error. While curl properly reads all 5 GB. |
@mcollina we should probably fix this before release. |
@indutny How come llhttp ends message without error before outputting content-length number of bytes? |
going back to undici@3 resolves the issue. |
Currently I'm at a loss on cause and fix for this. |
Isn't wasm memory space limited to Correction: 4gb |
The data is split? See the test. |
Looking. Completely unrelated, you should probably use |
llhttp itself appears to work fine: https://gist.github.com/indutny/818e4428eeadb17bb541a668e653e2a9 . Whenever I execute it - I get back exactly the same amount of bytes that passed to execute. I strongly suspect that it is either an issue with wasm build or the wrapping around it. |
@indutny Thanks for confirming. Much appreciated. |
@indutny I ported your test into our WebASsembly and was able to reproduce the issue: https://gist.github.com/ronag/3e316e78931f8b49f1138460a77a258a |
Added a bunch of logging and looks like
As you might have guessed 35944 is |
FWIW, here's the code that I've added to const _cl = new Uint32Array(llhttp.exports.memory.buffer, p + 8 * 4, 2);
const _remaining = _cl[1] * 0x100000000 + _cl[0];
console.log('parser.content_length=0x%s on_body_len=%d read_total=%d', _remaining.toString(16), len, _total += len); |
What's the best way to view the contents of the wasm file? |
Sounds like |
Maybe https://webassembly.studio? |
I know what's going on. Could you find |
That fixed it! |
Alright, working on the real fix. Thanks for trying it. |
On 32bit platforms `size_t` is essentially `uint32_t` (or at times even meager `uint16_t`). Loading `uint64_t` field value into `size_t` on these platforms would truncate the high bits and leave only the low 32 (16) bits in place. This leads to various interesting errors in downstream modules. See: - nodejs/llhttp#110 - nodejs/undici#803
Fix: nodejs/llparse#44 . @ronag could you try |
FWIW, this is the file that I intend to release once llparse fix lands. Feel free to ship the wasm version built from this file (after reviewing the diff) until we'll get it pushed upstream! |
On 32bit platforms `size_t` is essentially `uint32_t` (or at times even meager `uint16_t`). Loading `uint64_t` field value into `size_t` on these platforms would truncate the high bits and leave only the low 32 (16) bits in place. This leads to various interesting errors in downstream modules. See: - nodejs/llhttp#110 - nodejs/undici#803 This patch makes all field loads go into their respective types. Truncation doesn't happen in this case because C coercion rules will cast both types to the largest necessary datatype to hold either of them.
All good! |
Thank you for the help @indutny ! |
No worries. Always glad to fix my own mess ups 😂
…On Tue, May 11, 2021 at 23:41 Daniele Belardi ***@***.***> wrote:
Thank you for the help @indutny <https://github.com/indutny> !
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#803 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAB2HQ632KFBEM2ZR2JGJVTTNIPI3ANCNFSM44V2Z4ZQ>
.
|
On 32bit platforms `size_t` is essentially `uint32_t` (or at times even meager `uint16_t`). Loading `uint64_t` field value into `size_t` on these platforms would truncate the high bits and leave only the low 32 (16) bits in place. This leads to various interesting errors in downstream modules. See: - nodejs/llhttp#110 - nodejs/undici#803 This patch makes all field loads go into their respective types. Truncation doesn't happen in this case because C coercion rules will cast both types to the largest necessary datatype to hold either of them. PR-URL: #44 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Daniele Belardi <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Created a new release: https://github.com/nodejs/llhttp/releases/tag/release%2Fv6.0.2 |
Haven't had time to check but I suspect we might have a problem with body sizes larger than 31 bit.undici will complete without error before reading entire response body.
The text was updated successfully, but these errors were encountered: