Last updated: 2026-10-21
Helpers for reading inbound request headers at the Express layer. They read and normalise; they decide nothing. The boundary review behind this file is #95.
Role. Contract modules for the inbound side of a request, used by the mode code: the request-id middleware, which both mode routers mount, and the Authorization: Bearer grammar, which the validation path applies.
Owns: the Bearer grammar validation applies, and whether a refused header still named the Bearer scheme; the request id — the bounds on reusing an inbound one, generation, normalisation into req.headers, and the echo on the response.
Does not own: what a refused header is answered with (status, challenge, realm) — that is the validation decision's; the injection path's Authorization grammar (in modes/injection); where the middleware is mounted (each mode router); forwarding the id to the provider or upstream (the clients and the upstream stage in router/).
Why separate. Both are parsing of untrusted inbound headers, with no decision, configuration or I/O, kept apart from the modes that act on the result. Why they sit in express/ rather than beside their callers is not recorded.
node:crypto and Express types only; nothing else in src/. Imported only by modes/*.
- No decision, configuration, provider call, logging or state. Nothing here can fail or needs releasing.
- Two
Authorizationgrammars, one per path (#95 F16). This directory holds the one validation applies (bearer.mts: RFC 6750 §2.1 exactly — a case-sensitiveBearer, exactly one SP and ab64token, with nothing after it);modes/injectionholds the exchange's, which follows RFC 6750 / 9110 and narrows to a JWS compact JWT. Each path parses once and applies exactly one of them; the session path parses noAuthorizationat all. Why this grammar is stricter than RFC 9110 and RFC 6750 is in the doc comment onextractBearerToken. Pinned by__tests__/bearer.test.mts. - The request id is mounted first (#95 F17). The middleware writes the normalised id back into
req.headers, and every later reader — the request logs, the mode middlewares, the provider clients, the upstream stage — takes it from there. That is correct only because each mode router mounts it before anything else; mount nothing that reads the id in front of it. Not tested — no test pins the order. - Reuse over replace, within bounds. An inbound id is kept rather than replaced when it is 1 to 200 characters of
A-Z a-z 0-9 - . _ ~ + / =(ACCEPTED_IDinrequestId.mts); anything else — an empty value, an oversized one, one with whitespace, a control character, a separator or non-ASCII — is replaced by a fresh id, as an absent one is, and not logged. Two header lines arrive joined with,by Node and are replaced; of an array, the first value is the one bounded. Pinned by__tests__/requestId.test.mts.