fix(sharing): answer malformed request URLs instead of crashing the server

handle() is dispatched via `void`, so a throw before its try/catch is an
unhandled rejection on a LAN-facing server. A request target the HTTP
parser accepts but the WHATWG URL parser rejects (unterminated IPv6 host
like //[::1) threw at new URL() and hung/killed the process. Parse inside
a guard and answer 400. Mutation-checked: the test times out with an
unhandled error before the fix, passes after.
This commit is contained in:
ozymandiashh 2026-08-04 05:56:18 +03:00
parent 2c3319b286
commit 2b49608fd2
2 changed files with 70 additions and 1 deletions

View file

@ -73,11 +73,22 @@ export class ShareServer {
}
private async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {
const url = new URL(req.url ?? '/', 'https://localhost')
const json = (code: number, body: unknown): void => {
res.writeHead(code, { 'content-type': 'application/json' })
res.end(JSON.stringify(body))
}
// handle() is dispatched with `void` (see the createServer callback), so a
// throw here is an UNHANDLED rejection, not a caught 500. A request target
// the HTTP parser accepts but the WHATWG URL parser rejects - e.g. an
// unterminated IPv6 host like `//[::1` - would otherwise crash this
// LAN-facing server. Parse inside the guard and answer 400 instead.
let url: URL
try {
url = new URL(req.url ?? '/', 'https://localhost')
} catch {
json(400, { error: 'malformed request URL' })
return
}
try {
await this.route(url, req, res, json)
} catch (err) {