-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
Fetch sends incorrect number of chunks when given a ReadableStream with a Passthrough as body #55910
Comments
Update: my theory is that something goes wrong in ReadableStreamFrom(), which is called because a This is just a workaround for now. I'm trying to understand the issue with // index.js
const fs = require("fs");
const { PassThrough } = require("stream");
async function run() {
const readStream = fs.createReadStream("my-file.txt"); // you will need a file large enough (>0.5MB)
const passThrough = new PassThrough();
passThrough.on("data", (e) => {
console.log("chunk length", e.length);
});
readStream.pipe(passThrough);
const url = `http://localhost:8000`;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: ReadableStream.from(passThrough), // this is the workaround
duplex: "half",
});
console.log("response status:", response.status);
}
run(); |
Update: The issue was not in After more digging, here is the problematic sequence:
A better work-around than suggested above is therefore to ensure const passThrough = new PassThrough();
passThrough.on("data", (e) => {
console.log("chunk length", e.length);
});
passThrough.pause();
readStream.pipe(passThrough); Full fixed snippet: const fs = require("fs");
const { PassThrough } = require("stream");
async function run() {
const readStream = fs.createReadStream("my-file.txt");
const passThrough = new PassThrough();
passThrough.on("data", (e) => {
console.log("chunk length", e.length);
});
passThrough.pause();
readStream.pipe(passThrough);
const url = `http://localhost:8000`;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "text/plain",
},
body: passThrough,
duplex: "half",
});
console.log("response status:", response.status);
}
run(); I think this issue can be closed, but I'll leave it open for a couple days in case someone is willing to proof-check my reasoning. |
Version
Repro confirmed on at least v23.2.0, v20.14.0
Platform
Repro both on Linux and Windows
Subsystem
No response
What steps will reproduce the bug?
Run a basic HTTP server supporting HTTP chunked requests (
python3 server.py
):Write a long text in
my-file.txt
. The file must be large enough to be chunkable (~0.5MB). (Here is a sample file for your convenience).Run this NodeJS code (
node index.js
):How often does it reproduce? Is there a required condition?
This only happens when the ReadableStream passed as a body to the
fetch
function is piped into aPassthrough
.What is the expected behavior? Why is that the expected behavior?
The number of chunks read by the
Pipethrough
is identical to the number of chunks received by the HTTP server.What do you see instead?
The server consistently receives fewer chunks than were sent from the client:
Client (7 chunks):
Server (only 5 chunks):
The number of chunks effectively sent varies and seems somewhat random (sometimes 4, sometimes 5).
The issue does not occur when the ReadableStream is not piped through Pipethrough. This implies that the Pipethrough somehow impacts how
fetch
consumes the ReadableStream.Additional information
Apologies if I'm missing something. As far as I can tell, this is not the expected behavior of Pipethrough
The text was updated successfully, but these errors were encountered: