oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.25k stars 2.77k forks source link

`net.createServer` does not work with unix socket #8374

Open ghost opened 9 months ago

ghost commented 9 months ago

What version of Bun is running?

1.0.25

What platform is your computer?

Darwin 22.6.0 x86_64 i386

What steps can reproduce the bug?

Place the following code in index.js.

const fs = require('node:fs');
const net = require('node:net');
const os = require('node:os');
const path = require('node:path');

const pipePath = path.join(os.tmpdir(), 'test');
const server = net.createServer();

server.on('listening', () => console.log(`Now listening on ${pipePath}`));
server.listen({ path: pipePath });

process.on('SIGINT', function () {
    fs.unlink(pipePath, function (err) {
        if (err) console.log(err);
        else console.log(`Closed server and removed ${pipePath}`);

        process.exit();
    });
})

Run it with bun index.js and it will crash with the following error:

4 | const path = require('node:path');
5 | 
6 | const pipePath = path.join(os.tmpdir(), 'test');
7 | const server = net.createServer();
8 | server.on('listening', () => console.log(`Now listening on ${pipePath}`));
9 | server.listen({ path: pipePath });
    ^
TypeError: undefined is not an object
      at listen (node:net:539:17)
      at <redacted_path>/index.js:9:1

What is the expected behavior?

node index.js works fine so I would expect bun index.js to work fine too since I don't think I'm using any functionality from node:net that's not implement yet.

node --version
v18.19.0

What do you see instead?

No response

Additional information

No response

bompus commented 9 months ago

This bug also extends to node:http, however, there isn't an error on listen() with node:http, just node:net.

Even though node:http does not throw an error, it also does not create/listen on the unix domain socket.

This also breaks fastify when attempting to listen on a unix domain socket, because they use the optionsObject signature and pass { path: ... } to server.listen().

import { createServer } from 'node:http';

const server = createServer((req, res) => {
  console.log('connected');
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('connected');
  res.end();
});

server.on('listening', () => console.log('listening'));

// server.listen({ host: '127.0.0.1', port: 8123 }); // works 
// server.listen('/run/test.sock'); // works ( curl -i http://127.0.0.1/ --unix-socket /run/test.sock )
server.listen({ path: '/run/test.sock' }); // no error, but also does not create/listen this file, listens on http://[::]:3000 instead
import { createServer } from 'node:net';

const server = createServer();

server.on('listening', () => console.log('listening'));

// server.listen({ host: '127.0.0.1', port: 8123 }); // works
// server.listen('/run/test.sock'); // works ( curl -i http://127.0.0.1/ --unix-socket /run/test.sock )
server.listen({ path: '/run/test.sock' }); // error