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

Bun.serve fetch return new Response(Bun.file("test.jpg")); sometimes returns an empty response #7954

Open
TomasHubelbauer opened this issue Jan 3, 2024 · 2 comments · May be fixed by #9701
Labels
bug Something isn't working bun:serve Bun.serve and HTTP server

Comments

@TomasHubelbauer
Copy link

TomasHubelbauer commented Jan 3, 2024

What version of Bun is running?

1.0.20+09d51486e

What platform is your computer?

Darwin 23.2.0 arm64 arm

What steps can reproduce the bug?

index.js:

Bun.serve({
  async fetch(request) {
    if (request.url !== "http://localhost:3000/") {
      return new Response(Bun.file("test.jpg"));
    }

    let html = "";
    for (let index = 0; index < 100; index++) {
      html += `<img src="/${index}" onerror="console.log(this.src, 'failed to load');" />`;
    }

    return new Response(html, {
      headers: { "Content-Type": "text/html" },
    });
  },
});
  • Add any test.jpg image alongside index.js.
  • Run bun .
  • Visit http://localhost:3000/
  • Open the developer tools Console tab
  • Observe several images probably having failed to load

What is the expected behavior?

All images have loaded on the first try.

What do you see instead?

A random amount (between 2-10 % on different reloads) of the images fail to get served:
image

The request is actually a 200 but the response headers are written at the start of the response body instead of into the HTTP stream and then properly delimited it seems. I've also seen seemingly empty response bodies under different circumstances, but I don't have a repro for that now.

Observing the Network tab, for the failed requests, we can confirm the headers are written into the response body:
image

I can reproduce this almost every load in Firefox, every tenth load or so in Safari and seemingly never in Chrome. I guess different browser have different tolerance to the ways the HTTP payload can be (mis?)structured.

Additional information

I was on the fence about sending this in because at first it seemed like maybe it was a Firefox issue but when I reproduced in Safari I figured this probably is a Bun issue with how the HTTP payload is serialized. If I'm wrong, please accept my apologies.

@TomasHubelbauer TomasHubelbauer added the bug Something isn't working label Jan 3, 2024
@Electroid Electroid added the bun.js Something to do with a Bun-specific API label Jan 3, 2024
@Jarred-Sumner
Copy link
Collaborator

This is definitely a bug in Bun

I suspect we are writing the response headers and then not checking if they finished writing before we begin sendfile().

@dl-eric
Copy link

dl-eric commented Mar 19, 2024

I was using Elysia to serve static content and files would probabilistically return HTTP 400 with a zero-byte payload and '0' Content-Length header. I suspect it was due to an issue that is at least related to this issue. As a mitigation, I had to read in the file explicitly before Elysia sent it out, like so:

const file = Bun.file(...);
const res = new Response(await file.arrayBuffer(), {
	headers: { 'Content-Type': file.type }
});
return res;

while we should just be able to return it:

return Bun.file(...);

@dl-eric dl-eric linked a pull request Mar 29, 2024 that will close this issue
6 tasks
@Electroid Electroid added bun:serve Bun.serve and HTTP server and removed bun.js Something to do with a Bun-specific API labels Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working bun:serve Bun.serve and HTTP server
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants