mirror of
https://github.com/HeyPuter/puter.git
synced 2026-11-05 13:35:20 +00:00
routing fixes
This commit is contained in:
1 parent
f61b3ea546
commit
df9ce2c76f
2 files changed
+79
-9
No files matched your search
@@ -468,6 +468,58 @@ describe('PuterServer host header validation — permissive modes', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('PuterServer host header validation — custom domains with every host accepted', () => {
|
||||
let server: PuterServer;
|
||||
let port: number;
|
||||
|
||||
beforeAll(async () => {
|
||||
port = await allocateEphemeralPort();
|
||||
server = await setupTestServer(
|
||||
{
|
||||
port,
|
||||
domain: 'puter.localhost',
|
||||
origin: `http://puter.localhost:${port}`,
|
||||
allow_all_host_values: true,
|
||||
custom_domains_enabled: true,
|
||||
static_hosting_domain: 'site.puter.localhost',
|
||||
} as unknown as IConfig,
|
||||
{ listen: true },
|
||||
);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await server?.shutdown();
|
||||
});
|
||||
|
||||
it('still hands a host outside our domains to site hosting', async () => {
|
||||
const res = await rawRequest(port, '/', {
|
||||
host: 'www.my-own-domain.example',
|
||||
});
|
||||
expect(res.status).toBe(404);
|
||||
expect(res.body).toBe('Site not found');
|
||||
});
|
||||
|
||||
it('leaves our own domain to the GUI', async () => {
|
||||
const res = await rawRequest(port, '/healthcheck', {
|
||||
host: `puter.localhost:${port}`,
|
||||
});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('never treats an IP or localhost as a custom domain', async () => {
|
||||
for (const host of [
|
||||
`127.0.0.1:${port}`,
|
||||
`[::1]:${port}`,
|
||||
`localhost:${port}`,
|
||||
]) {
|
||||
const res = await rawRequest(port, '/healthcheck', { host });
|
||||
expect(res.status, host).toBe(200);
|
||||
const root = await rawRequest(port, '/', { host });
|
||||
expect(root.body, host).not.toBe('Site not found');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('PuterServer request parsing', () => {
|
||||
let server: PuterServer;
|
||||
let port: number;
|
||||
|
||||
+27
-9
@@ -29,6 +29,7 @@ import path from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { parseArgs } from 'node:util';
|
||||
import http from 'node:http';
|
||||
import { isIP } from 'node:net';
|
||||
import { puterClients } from './clients';
|
||||
import { puterControllers } from './controllers';
|
||||
import { createAuthProbe } from './core/http/middleware/authProbe';
|
||||
@@ -597,7 +598,32 @@ export class PuterServer {
|
||||
|
||||
// Build the allowed-domain set from config.
|
||||
this.#app.use((req, res, next) => {
|
||||
const hostName = (req.headers.host ?? '')
|
||||
.split(':')[0]
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
const isOwnHost =
|
||||
!hostName ||
|
||||
this.#getAllowedDomains().some((d) =>
|
||||
PuterServer.#hostMatchesDomain(hostName, d),
|
||||
);
|
||||
|
||||
// Accepting every host still has to tell custom domains apart, or
|
||||
// they fall through to the API/GUI instead of site hosting. An IP
|
||||
// or localhost is never one: load balancer health checks and
|
||||
// in-cluster callers address the server that way.
|
||||
if (config.allow_all_host_values) {
|
||||
if (
|
||||
config.custom_domains_enabled &&
|
||||
!isOwnHost &&
|
||||
req.path !== '/healthcheck' &&
|
||||
// `[` is what an IPv6 literal's `[::1]:port` splits to.
|
||||
!hostName.startsWith('[') &&
|
||||
isIP(hostName) === 0 &&
|
||||
hostName !== 'localhost'
|
||||
) {
|
||||
req.is_custom_domain = true;
|
||||
}
|
||||
next();
|
||||
return;
|
||||
}
|
||||
@@ -613,15 +639,7 @@ export class PuterServer {
|
||||
return;
|
||||
}
|
||||
|
||||
const hostName = (req.headers.host ?? '')
|
||||
.split(':')[0]
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
const allowed = this.#getAllowedDomains();
|
||||
|
||||
if (
|
||||
allowed.some((d) => PuterServer.#hostMatchesDomain(hostName, d))
|
||||
) {
|
||||
if (isOwnHost) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user