┌─────────────────────────────────────────────────────────────────┐
│ cors — fine-grained, high-performance CORS for zx web servers │
└─────────────────────────────────────────────────────────────────┘
CORS middleware for std.http servers in zz. Deny by default,
secure-by-default configuration, sub-microsecond hot path, zero
per-request regex compilation, and full socket-less test coverage.
zz add corsimport cors
import std.http
func main() {
s := http.server()
s = s.route("GET", "/api/hi", |_req| "hi")
s = cors.middleware(s, cors.allow(["https://app.example.com"]))
http.listen(s, 8080) ?? println("failed to start server")
}
cors.config() denies every origin. Opt into each behavior:
cfg := cors.config()
cfg = cors.set_allow_origin(cfg, "https://app.example.com")
cfg = cors.set_allow_credentials(cfg, true) // never combined with "*"
cfg = cors.set_max_age(cfg, 86400) // preflight cache
s = cors.middleware(s, cfg)
Or use shorthand constructors:
cors.allow(["https://app.example.com"]) // exact match list
cors.allow_all() // "*" — NO credentials
cors.dynamic(|o: str| str.ends_with(o, ".example.com")) // func matcher
| Function | Description |
|---|---|
cors.config() |
Secure default: deny-all config |
cors.allow(origins) |
Config with exact-match origins |
cors.allow_all() |
Config allowing any origin (*) |
cors.dynamic(fn) |
Config with func(origin) -> bool matcher |
cors.middleware(server, config) |
Attach CORS to a server |
cors.with(server, config) |
Alias for middleware |
cors.origin_ok(config, origin) |
Pure origin check (testable) |
set_allow_origin, set_allow_origin_regex, set_allow_origin_fn,
set_allow_credentials, set_expose_headers, set_allow_methods,
set_allow_headers, set_max_age, set_vary_origin,
set_preflight_status, set_preflight_passthrough,
set_reflect_origin
Each returns a new config (immutable-by-value style).
| Scenario | Result |
|---|---|
No Origin header |
Request untouched, no CORS headers |
| Allowed origin | ACAO: <origin>, plus Vary: Origin if dynamic |
| Denied origin | 403 "cors: origin not allowed" |
allow_all() |
ACAO: * |
| Credentials + wildcard | Build-time error; never emitted at runtime |
| OPTIONS preflight + allowed origin | 204 + ACAM, ACAH, ACMA (if >0) |
preflight_passthrough |
OPTIONS falls to route handler |
null origin (file://) |
Denied unless explicitly configured |
- Never
*+ credentials — build-time error. - Never reflect arbitrary
Origin— opt-in viaset_reflect_origin(true). - Deny by default — empty origins = no CORS headers.
- Preflight only for OPTIONS — other methods never short-circuited.
examples/basic.zz— minimal allow-list setupexamples/dynamic.zz- func matcher for subdomainsexamples/credentials.zz— cookies + expose headersexamples/preflight_passthrough.zz— OPTIONS to routes
docs/api.md— every function and signature
MIT — see LICENSE.