Skip to content

TCP Socket context data is unexpectedly shared among all sockets #25357

@xuxucode

Description

@xuxucode

What version of Bun is running?

1.3.3+274e01c73

What platform is your computer?

Darwin 23.3.0 arm64 arm

What steps can reproduce the bug?

The context data is supposed to be one instance per socket, but when data: {} is passed to the Bun.listen method, the context data is shared among all sockets.

Run below code to reproduce:

import assert from 'node:assert';

type SocketData = { sessionId?: number };

Bun.listen<SocketData>({
  hostname: "localhost",
  port: 8080,
  // 1. Initialize the `data` object
  data: { },
  socket: {
    open(socket) {
      // 3. Assertion failed due to above initialized `data: {}`.
      assert.ok(socket.data.sessionId === undefined, 'initial data per socket should be undefined')
      socket.data.sessionId = Date.now();
    },
    data(socket, data) {
      const body = `${socket.data.sessionId}: ack`
      socket.write('HTTP/1.1 200 OK\r\n')
      socket.write(`Content-Length: ${body.length}\r\n`)
      socket.write("\r\n")
      socket.end(`${socket.data.sessionId}: ack`); // end connection
    },
    close(socket, err) {
      console.log('socket close:', err)
    },
    error(socket, err) {
      console.error('socket error:', err)
    }
  },
});

// 2. Sending multiple requests caused the `data` is reused.
for (let i = 0; i < 2; i++) {
  const session = await fetch('http://localhost:8080').then(res => res.text())
  console.log('session:', session)
}

What is the expected behavior?

One context data instance per socket

What do you see instead?

Context data is reused/shared

Additional information

Context data will not be shared when data: {} is not passed to Bun.listen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions