Request headers
HTTP headers reveal browser identity and request context. STATIC’s header stage reads the selected profile and mutates the parsed request before the upstream fetcher sends it. The same stage is used for ordinary HTTP/1.1 requests and individual HTTP/2 streams; their downstream protocol handlers remain different.
Rule order
Before profile rules, STATIC removes conditional cache validators from eligible HTML navigations and script/bootstrap asset requests. For HTML navigations it also strips zstd from Accept-Encoding so later HTML mutation can work with the accepted encodings.
The rules then run in this order:
| Rule | Current behavior |
|---|---|
remove | Delete the named header. |
replace | Change its value only if present. |
replaceArbitrary | Also changes an existing value; the current handler applies it like replace. |
replaceDynamic | Choose a replacement from request path, content type, and existing header value. |
set | Add a value only if absent. |
append | Add another value, including alongside existing values. |
The catalog’s pass list is parsed into rules, but the current apply_profile_rules implementation does not use it to implement an allowlist. Do not infer that a header outside pass is blocked.
Identity and Client Hint consistency
After generic header rules, identity normalization uses the effective browser policy for the user agent and supported Client Hint fields. Existing/cached hint headers are mapped to the selected identity rather than retaining host values; unexpected identity hints are removed. It does not send every high-entropy field merely because the profile defines it.
Covered mappings include platform, architecture, bitness, model, platform version, full versions, WoW64 and form factors. Form factors are strings, not brand records. A policy without UA Client Hints suppresses those identity headers rather than advertising native Chromium data. JavaScript normalization is a separate realm operation, so verify both paths using the same selected policy.
Changing a profile applies to new Flows; an existing page can retain its previous runtime until navigation/reload. Requests after Accept-CH, cached hint state and real browser operation are useful consistency checks. Generic rule ordering or a plausible UA string alone is not browser fidelity.
Why context matters
The shipped Chrome profile, for example, specifies User-Agent, Accept-Language, and Client Hint replacements and has a dynamic Accept map. A document navigation and an image request should not automatically share the same Accept value. Existing Cookie and Authorization values are not synthesized into a new identity by the profile.
The upstream fetcher reconstructs the request for wreq, reconciles body length headers, and uses its transport client’s supported header ordering. Changing a JSON array does not promise byte-for-byte control over the eventual wire representation. HTTP/2 pseudo-headers and connection settings are addressed separately in HTTP/2.
Response headers are another stage
The header-profile stage primarily changes requests. Response changes come from CSP and HTML injection and Alt-Svc handling. Alt-Svc may advertise an alternative path that bypasses the intended proxy behavior, so STATIC can normalize, redirect, or remove it according to config. Bootstrap script responses also get cache validators removed and cache-control suitable for the local/transformed asset.
Implementation: header rules, fetcher, and Alt-Svc stage.