(req: http.IncomingMessage, logger: Logger)
| 46 | const FORWARDED_HOST_IPV6_RE = /^\[[0-9a-fA-F:.]+\](:\d+)?$/; |
| 47 | |
| 48 | export function requestBase(req: http.IncomingMessage, logger: Logger): string { |
| 49 | // Honor x-forwarded-proto and x-forwarded-host so generated URLs survive a |
| 50 | // TLS-terminating or host-rewriting proxy in front of the mock. First |
| 51 | // non-empty value wins on comma-joined lists. |
| 52 | const candidate = firstForwardedValue(req.headers["x-forwarded-proto"])?.toLowerCase(); |
| 53 | // Allowlist http/https — any other value (ws, junk header data) falls back. |
| 54 | const proto = candidate === "http" || candidate === "https" ? candidate : "http"; |
| 55 | // Like the proto allowlist, a forwarded host that doesn't look like a bare |
| 56 | // host[:port] (or a bracketed IPv6 literal) falls back to the Host header — |
| 57 | // with a warn, so a misconfigured proxy isn't silently ignored. |
| 58 | const fwdHost = firstForwardedValue(req.headers["x-forwarded-host"]); |
| 59 | // The Host fallback gets the same host[:port] validation — a junk Host |
| 60 | // (e.g. "evil.com/path") could otherwise smuggle URL structure into the |
| 61 | // generated URLs. No warn: a missing/odd Host is transport-level noise, |
| 62 | // unlike a misconfigured proxy's x-forwarded-host. |
| 63 | const rawHost = req.headers.host; |
| 64 | let host = |
| 65 | rawHost !== undefined && |
| 66 | (FORWARDED_HOST_RE.test(rawHost) || FORWARDED_HOST_IPV6_RE.test(rawHost)) |
| 67 | ? rawHost |
| 68 | : "localhost"; |
| 69 | if (fwdHost !== undefined) { |
| 70 | if (FORWARDED_HOST_RE.test(fwdHost) || FORWARDED_HOST_IPV6_RE.test(fwdHost)) { |
| 71 | host = fwdHost; |
| 72 | } else { |
| 73 | logger.warn( |
| 74 | `x-forwarded-host value rejected, falling back to Host header: ${JSON.stringify(fwdHost.slice(0, 100))}`, |
| 75 | ); |
| 76 | } |
| 77 | } |
| 78 | return `${proto}://${host}`; |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Query-string suffix embedding the request's testId into generated URLs |
no test coverage detected
searching dependent graphs…