ai_api / src /shared /constants /upstreamHeaders.ts
Yogesh
initial deploy
cd8bd0a
Raw
History Blame Contribute Delete
1.5 kB
/**
* User-supplied upstream extra headers: names we never forward (Host / hop-by-hop / framing).
* Changing this list requires syncing: `sanitizeUpstreamHeadersMap` (models.ts), Zod
* `upstreamHeaderNameSchema` / record refine (schemas.ts), and `upstream-headers-sanitize` tests.
*/
const FORBIDDEN = new Set(
[
"host",
"connection",
"content-length",
"keep-alive",
"proxy-connection",
"transfer-encoding",
"te",
"trailer",
"upgrade",
].map((s) => s.toLowerCase())
);
export function isForbiddenUpstreamHeaderName(name: string): boolean {
return FORBIDDEN.has(String(name).trim().toLowerCase());
}
/**
* Auth headers that must come from the connection's credentials, never from
* operator-set per-provider custom headers. Kept here as the single source of
* truth so the Zod `customHeadersSchema` (schemas.ts) and the executor's
* apply-loop (open-sse/executors/default.ts) cannot drift apart.
*/
const FORBIDDEN_AUTH = new Set(
["authorization", "x-api-key", "x-goog-api-key", "api-key"].map((s) => s.toLowerCase())
);
/**
* Forbidden for operator-supplied custom headers: the hop-by-hop/framing set
* PLUS auth headers (owned by the credential layer). Use this in both the
* validation schema and the executor so there is one canonical denylist.
*/
export function isForbiddenCustomHeaderName(name: string): boolean {
const n = String(name).trim().toLowerCase();
return isForbiddenUpstreamHeaderName(n) || FORBIDDEN_AUTH.has(n);
}