cloudflare / cloudflare/workers-sdk
🐛 BUG: miniflare.dispatchFetch() buffers streaming responses
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.5k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 186
Description
### Which Cloudflare product(s) does this pertain to?
Miniflare
### What versions are you using?
3.20241230.0[miniflare]
### What operating system and version are you using?
OSX 15.2
### Please provide a link to a minimal reproduction
_No response_
### Describe the Bug
I'm using miniflare in test to assert my app is delivering the expected chunks in a streamed response. When I run the miniflare server locally and hit the endpoint using `curl` I get the expected chunks delivered as soon as they are enqueued. When I use `miniflare.dispatchFetch()` the chunks are all delivered at once when the stream is closed, suggesting that `.dispatchFetch` is somehow buffering the response internally?
## Worker server code:
```ts
export const routeHandler = (request, env) => {
const stream = new ReadableStream({
async start(controller) {
const encoder = new TextEncoder();
let i = 0;
while (i++ < 3) {
controller.enqueue(encoder.encode(`${i}\n`));
console.log('enqueue', i);
await wait(1000);
}
controller.close();
}
});
const response = new Response(stream, {
headers: {
'content-type': 'text/plain',
'transfer-encoding': 'chunked',
},
});
return response;
};
```
## Client code
```ts
const res = await miniflare.dispatchFetch(
new URL('/cache/url/stream', 'http://localhost:4000/').toString(),
{
method: 'GET',
}
);
if (!res.body || !(res.body instanceof ReadableStream)) {
throw new Error('expected stream');
}
console.log('got status', res.status);
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
console.log(decoder.decode(value));
if (done) {
break;
}
}
```
## Log output
```bash
[mf:inf] Ready on http://127.0.0.1:4000
enqueue 1
got status 200
[mf:inf] GET /cache/url/stream 200 OK (13ms)
enqueue 2
enqueue 3
1
2
3
```
Note how the client logs all happen after the final chunk is enqueued and the stream is closed.
### Please provide any relevant error logs
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.