Skip to content

Commit f798275

Browse files
committed
Allow node adapter to be configured to have node server listen to socket path instead of host and port
1 parent 3e30a1b commit f798275

File tree

4 files changed

+95
-6
lines changed

4 files changed

+95
-6
lines changed

packages/adapter-node/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const pipe = promisify(pipeline);
2525
* out?: string;
2626
* precompress?: boolean;
2727
* env?: {
28+
* path?: string;
2829
* host?: string;
2930
* port?: string;
3031
* };
@@ -34,7 +35,7 @@ const pipe = promisify(pipeline);
3435
export default function ({
3536
out = 'build',
3637
precompress,
37-
env: { host: host_env = 'HOST', port: port_env = 'PORT' } = {},
38+
env: { path: path_env = 'SOCKET_PATH', host: host_env = 'HOST', port: port_env = 'PORT' } = {},
3839
esbuild: esbuildConfig
3940
} = {}) {
4041
/** @type {import('@sveltejs/kit').Adapter} */
@@ -58,7 +59,9 @@ export default function ({
5859
utils.copy(files, '.svelte-kit/node');
5960
writeFileSync(
6061
'.svelte-kit/node/env.js',
61-
`export const host = process.env[${JSON.stringify(
62+
`export const path = process.env[${JSON.stringify(
63+
path_env
64+
)}] || false;\nexport const host = process.env[${JSON.stringify(
6265
host_env
6366
)}] || '0.0.0.0';\nexport const port = process.env[${JSON.stringify(port_env)}] || 3000;`
6467
);

packages/adapter-node/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"@sveltejs/kit": "workspace:*",
3030
"c8": "^7.7.2",
3131
"compression": "^1.7.4",
32+
"http-proxy": "^1.18.1",
3233
"node-fetch": "^3.0.0-beta.9",
3334
"polka": "^1.0.0-next.15",
3435
"rollup": "^2.55.0",

packages/adapter-node/src/index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
// TODO hardcoding the relative location makes this brittle
22
import { init, render } from '../output/server/app.js'; // eslint-disable-line import/no-unresolved
3-
import { host, port } from './env.js'; // eslint-disable-line import/no-unresolved
3+
import { path, host, port } from './env.js'; // eslint-disable-line import/no-unresolved
44
import { createServer } from './server';
55

66
init();
77

8-
const instance = createServer({ render }).listen(port, host, () => {
9-
console.log(`Listening on ${host}:${port}`);
10-
});
8+
const instance = createServer({ render });
9+
10+
if (path) {
11+
instance.listen(path, () => {
12+
console.log(`Listening on ${path}`);
13+
});
14+
} else {
15+
instance.listen(port, host, () => {
16+
console.log(`Listening on ${host}:${port}`);
17+
});
18+
}
1119

1220
export { instance };
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { test } from 'uvu';
2+
import { createServer } from '../src/server.js';
3+
import * as assert from 'uvu/assert';
4+
import fetch from 'node-fetch';
5+
import httpProxy from 'http-proxy';
6+
import fs from 'fs';
7+
8+
const PROXY_PORT = 9090;
9+
const { SOCKET_PATH = '/tmp/socket' } = process.env;
10+
const DEFAULT_SERVER_OPTS = { render: () => {} };
11+
12+
function cleanupSocketFile() {
13+
if (fs.existsSync(SOCKET_PATH)) {
14+
fs.unlinkSync(SOCKET_PATH);
15+
}
16+
}
17+
18+
function createProxy() {
19+
const proxy = httpProxy.createProxyServer({
20+
target: {
21+
socketPath: SOCKET_PATH
22+
},
23+
xfwd: true,
24+
secure: false
25+
});
26+
proxy.listen(PROXY_PORT);
27+
return proxy;
28+
}
29+
30+
function startServer(opts = DEFAULT_SERVER_OPTS) {
31+
const server = createServer(opts);
32+
return new Promise((fulfil, reject) => {
33+
server.listen(SOCKET_PATH, (err) => {
34+
if (err) {
35+
reject(err);
36+
}
37+
fulfil(server);
38+
});
39+
});
40+
}
41+
42+
test('starts a server listening on a path (domain socket file)', async () => {
43+
const server = await startServer();
44+
assert.ok('server started');
45+
server.server.close();
46+
cleanupSocketFile();
47+
});
48+
49+
test('serves a 404 via path', async () => {
50+
const server = await startServer();
51+
const proxy = createProxy();
52+
const res = await fetch(`http://localhost:${PROXY_PORT}/nothing`);
53+
assert.equal(res.status, 404);
54+
server.server.close();
55+
proxy.close();
56+
cleanupSocketFile();
57+
});
58+
59+
test('responses with the rendered status code via path', async () => {
60+
const server = await startServer({
61+
render: () => {
62+
return {
63+
headers: 'wow',
64+
status: 203,
65+
body: 'ok'
66+
};
67+
}
68+
});
69+
const proxy = createProxy();
70+
const res = await fetch(`http://localhost:${PROXY_PORT}/wow`);
71+
assert.equal(res.status, 203);
72+
server.server.close();
73+
proxy.close();
74+
cleanupSocketFile();
75+
});
76+
77+
test.run();

0 commit comments

Comments
 (0)