Request path
STATIC handles each parsed request as a Flow: request parts, an optional response, and metadata such as the selected profile, protocol labels, CSP nonce, and transport notes. An HTTP/2 stream gets its own Flow; it is not one Flow for the whole connection.
From socket to Flow
The listener first peeks at the incoming bytes. An HTTP CONNECT receives 200 Connection Established, then proceeds to a client-facing TLS handshake. A direct TLS connection enters that handshake immediately. A plain HTTP proxy request uses the HTTP/1.1 path without TLS interception. Unknown input is rejected. STATIC issues a certificate for the requested name from its own local CA during TLS interception.
After client TLS negotiation, h2 ALPN enters the HTTP/2 server path; other negotiated values enter HTTP/1.1. The browser-side protocol and the origin-side protocol are distinct. STATIC makes a new upstream request; it does not pass the browser’s TLS bytes directly to the website. See TLS and certificates.
What each stage changes
The ordered stages are HeaderProfileStage → BehavioralNoiseStage → CspStage → JsInjectionStage → AltSvcStage. Each stage has separate request, response-header, response-body, and finalization hooks; a stage may do nothing in a particular hook.
| Stage | Current responsibility |
|---|---|
| Header profile | Selects the materialized profile, annotates Flow metadata, applies request header rules and cache-sensitive request handling. |
| Behavioral noise | Creates a per-Flow plan and marks responses; the Rust augmentation of marked JSON bodies is still a placeholder, not a complete behavioral imitation. |
| CSP | Reads or generates a nonce and rewrites applicable response CSP after injection. |
| JS injection | Decodes eligible HTML, inserts a local runtime script and profile config, and marks the response. |
| Alt-Svc | Normalizes, redirects, or removes alternative-service advertisements according to configuration. |
The upstream fetcher receives the mutated request and any transport plan, performs the origin request, and returns a response. The response hooks then run before STATIC writes back to the browser. Request headers and HTML injection and CSP cover the mutations in detail.
Paths that differ
- HTTP/1.1 buffers an ordinary request and response before sending the staged response.
- HTTP/2 handles concurrent streams; it buffers HTML and script/bootstrap assets for possible mutation and streams other response bodies after header processing.
- The local
/__static/runtime.jsasset is served by STATIC without an origin fetch. - WebSocket upgrades use separate raw tunnel handling and bypass the ordinary response-body mutation path. Their upstream TLS path is not the same profile-driven
wreqfetcher.
Body size limits can end a Flow with an error rather than silently falling back to an unmodified response. Consult the connection handler, Flow model, and stage pipeline for the implementation.