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

πŸ› Bug Report β€” Runtime APIs: successive fetch()es fail if upstream doesn't consume body #1741

Open
mrbbot opened this issue Feb 28, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@mrbbot
Copy link
Contributor

mrbbot commented Feb 28, 2024

Hey! πŸ‘‹ When investigating cloudflare/workers-sdk#5095, we observed Network connection lost errors from successive calls to fetch() if the upstream didn't consume the request body. Specifically, every other request would fail. See https://github.com/mrbbot/workerd-network-connection-lost-repro for a minimal reproduction. Uncommenting this line https://github.com/mrbbot/workerd-network-connection-lost-repro/blob/04b2a464c8c269fb467ca5247efbb6da2303c9f5/user.capnp#L19 "fixes" the issue. It also seems like this line https://github.com/mrbbot/workerd-network-connection-lost-repro/blob/04b2a464c8c269fb467ca5247efbb6da2303c9f5/index.mjs#L32 needs to create a body with at least 2**16 + 1 bytes to trigger a reproduction.

This issue feels related to #1376 and #960. In #960 (comment), it was suggested that workerd should be canceling the upload in cases where a response is returned without reading the body. It feels like the same thing should be happening here.

/cc @petebacondarwin @RamIdeas

@petebacondarwin
Copy link
Contributor

I also note that calling await request.body.cancel() does not "fix" the issue either. We actually have to drain the body stream.

@petebacondarwin petebacondarwin added the bug Something isn't working label Feb 28, 2024
@kentonv
Copy link
Member

kentonv commented Feb 28, 2024

I suspect the HTTP client side thinks the connection is done and available for reuse: It has sent its entire request and received a response. However, what the client doesn't know is that the request body is still sitting in the socket buffer. On the server side, if the response completes without fully reading the request, the HTTP implementation will read and discard up to 64k, and then give up and close the connection.

I'm not entirely sure how to solve this without disabling connection reuse entirely.

Perhaps we should always send Connection: close when the response headers are sent without having read the entire request body?

(This should be fixed in KJ HTTP, probably. Not workerd.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants