Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion skills/convert-site/scripts/review-serve.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ async function serveForeground({ dir, port }) {
if (err.code === 'EADDRINUSE') fail(inUse(port, lsofListener(port) ?? { pid: 'unknown', command: 'unknown command' }));
else fail(new UsageError(`cannot listen on port ${port}: ${err.message}`));
});
server.listen(port, done);
server.listen(port, '127.0.0.1', done);
});
const stop = () => server.close(() => process.exit(0));
process.once('SIGTERM', stop);
Expand Down
15 changes: 14 additions & 1 deletion test/convert/review-serve.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createServer } from 'node:http';
import { createServer as createNetServer } from 'node:net';
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { gzipSync } from 'node:zlib';
import { tmpdir } from 'node:os';
import { networkInterfaces, tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { startFixture } from '../fixture/serve.mjs';
import { compileSource, fillDestination } from '../../skills/convert-site/scripts/lib/review-routes.mjs';
Expand Down Expand Up @@ -194,6 +194,19 @@ test('serves dist/, applies vercel.json redirects and rewrites, proxies other or
}
});

test('listens on loopback only, not on the machine\'s network addresses', async (t) => {
const external = Object.values(networkInterfaces()).flat().find((a) => a.family === 'IPv4' && !a.internal);
if (!external) return t.skip('no non-loopback IPv4 address on this machine');
const port = await freePort();
const { child } = await serve(['--dir', site, '--port', String(port)]);
try {
assert.equal((await fetch(`http://127.0.0.1:${port}/`)).status, 200);
await assert.rejects(fetch(`http://${external.address}:${port}/`));
} finally {
child.kill('SIGTERM');
}
});

test('a port held by another process exits 2 naming the pid instead of binding another interface', async () => {
const holder = createNetServer();
await new Promise((done) => holder.listen(0, '127.0.0.1', done));
Expand Down
Loading