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

http.ServerResponse only flushes content automatically to network after second write call #5869

Open
arthurfiorette opened this issue Sep 21, 2023 · 1 comment
Labels
bug Something isn't working node.js Compatibility with Node.js APIs

Comments

@arthurfiorette
Copy link

What version of Bun is running?

1.0.2+37edd5a6e389265738e89265bcbdf2999cb81a49

What platform is your computer?

Linux 5.15.90.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

When creating a http server and piping a stream into the response, it does not flushes the content in the first write, only after the second.

import http from 'http'
import { PassThrough } from 'stream'

http
  .createServer((req, res) => {
    res.setHeader('Content-Type', 'text/html; charset=utf-8')

    const stream = new PassThrough()
    stream.pipe(res)

    if (req.url === '/single') {
      stream.write('hello')
    }

    if (req.url === '/double') {
      stream.write('hello')
      stream.write(' world')
    }

    // Does not ends the stream because ending
    // would forcefully flush contents.
  })
  .listen(8080, () => {
    console.log('http://localhost:8080')
  })

What is the expected behavior?

Calling localhost:8080/single would output hello and calling localhost:8080/double would still print hello world.

This behaviour is right in nodejs:

# prints hello in nodejs
curl http://localhost:8080/single -vN
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /single HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
hello
# prints hello world in nodejs
curl http://localhost:8080/double -vN
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /double HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Date: Thu, 21 Sep 2023 19:23:46 GMT
< Transfer-Encoding: chunked
< 
hello world

What do you see instead?

Calling localhost:8080/single would never give any output:

# Does not prints hello
curl http://localhost:8080/single -vN
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /single HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 

Calling localhost:8080/double would give both generated output:

# Prints hello world
curl http://localhost:8080/double -vN
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /double HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Date: Thu, 21 Sep 2023 19:23:46 GMT
< Transfer-Encoding: chunked
< 
hello world

Additional information

No response

@arthurfiorette arthurfiorette added the bug Something isn't working label Sep 21, 2023
@arthurfiorette arthurfiorette changed the title http.ServerResponse only flushes after second write http.ServerResponse only flushes content automatically to network after second write call Sep 21, 2023
@Electroid Electroid added the node.js Compatibility with Node.js APIs label Sep 21, 2023
@EmNudge
Copy link

EmNudge commented Apr 20, 2024

Ran into the same issue. Here is a slightly different example to see this in the browser.

node index.mjs will work fine, whereas bun run index.mjs will wait a full 2 seconds before rendering any part of the page.

import { createServer } from "node:http";

createServer((_req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/html",
    "Transfer-Encoding": "chunked",
  });

  res.write(`
    <html>
      <head>
        <title>Hello Page!</title>
      </head>
      <body>
        <h1>Hello</h1>
  `);

  // Uncomment this line to fix bun
  // res.write('')

  setTimeout(() => {
    res.write(`
        <h2>World</h2>
        <style>h1 { background: aqua }</style>
      </body>
    </html>
    `);
    res.end();
  }, 2000);
}).listen(8080);

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

No branches or pull requests

3 participants