HTTP Middleware
HTTP Middleware
Section titled “HTTP Middleware”Middleware processes HTTP requests before and after route handling.
How Middleware Works
Section titled “How Middleware Works”Middleware wraps HTTP handlers to add processing logic. Each middleware receives an options map and returns a handler wrapper:
middleware: - cors - ratelimitoptions: cors.allow.origins: "https://example.com" ratelimit.requests: "100"Options use dot notation: middleware_name.option.name. Legacy underscore format is supported for backward compatibility.
Pre-Match vs Post-Match
Section titled “Pre-Match vs Post-Match”middleware: # Pre-match - cors - compressoptions: cors.allow.origins: "*"
post_middleware: # Post-match - endpoint_firewallpost_options: endpoint_firewall.action: "access"Available Middleware
Section titled “Available Middleware”CORS {#cors}
Section titled “CORS {#cors}”Cross-Origin Resource Sharing for browser requests.
middleware: - corsoptions: cors.allow.origins: "https://app.example.com" cors.allow.credentials: "true"| Option | Default | Description |
|---|---|---|
cors.allow.origins | * | Allowed origins (comma-separated, supports *.example.com) |
cors.allow.methods | GET,POST,PUT,DELETE,OPTIONS,PATCH | Allowed methods |
cors.allow.headers | Origin,Content-Type,Accept,Authorization,X-Requested-With | Allowed request headers |
cors.expose.headers | - | Headers exposed to client |
cors.allow.credentials | false | Allow cookies/auth |
cors.max.age | 86400 | Preflight cache (seconds) |
cors.allow.private.network | false | Private network access |
OPTIONS preflight requests are handled automatically.
Rate Limiting {#ratelimit}
Section titled “Rate Limiting {#ratelimit}”Token bucket rate limiting with per-key tracking.
middleware: - ratelimitoptions: ratelimit.requests: "100" ratelimit.window: "1m" ratelimit.key: "ip"| Option | Default | Description |
|---|---|---|
ratelimit.requests | 100 | Requests per window |
ratelimit.window | 1m | Time window |
ratelimit.burst | 20 | Burst capacity |
ratelimit.key | ip | Key strategy |
ratelimit.cleanup_interval | 5m | Cleanup frequency |
ratelimit.entry_ttl | 10m | Entry expiration |
ratelimit.max_entries | 100000 | Max tracked keys |
Key strategies: ip, header:X-API-Key, query:api_key
Returns 429 Too Many Requests with headers: X-RateLimit-Limit, X-RateLimit-Window.
Compression {#compress}
Section titled “Compression {#compress}”Gzip compression for responses.
middleware: - compressoptions: compress.level: "default" compress.min.length: "1024"| Option | Default | Description |
|---|---|---|
compress.level | default | fastest, default, or best |
compress.min.length | 1024 | Minimum response size (bytes) |
Only compresses when client sends Accept-Encoding: gzip.
Real IP {#real_ip}
Section titled “Real IP {#real_ip}”Extract client IP from proxy headers.
middleware: - real_ipoptions: real_ip.trusted.subnets: "10.0.0.0/8,172.16.0.0/12"| Option | Default | Description |
|---|---|---|
real_ip.trusted.subnets | Private networks | Trusted proxy CIDRs |
real_ip.trust_all | false | Trust all sources (insecure) |
Header priority: True-Client-IP > X-Real-IP > X-Forwarded-For
Token Auth {#token_auth}
Section titled “Token Auth {#token_auth}”Token-based authentication. See Security for token store configuration.
middleware: - token_authoptions: token_auth.store: "app:tokens"| Option | Default | Description |
|---|---|---|
token_auth.store | required | Token store registry ID |
token_auth.header.name | Authorization | Header name |
token_auth.header.prefix | Bearer | Header prefix |
token_auth.query.param | x-auth-token | Query parameter fallback |
token_auth.cookie.name | x-auth-token | Cookie fallback |
Sets actor and security scope in context for downstream middleware. Does not block requests—authorization happens in firewall middleware.
Metrics {#metrics}
Section titled “Metrics {#metrics}”Prometheus-style HTTP metrics. No configuration options.
middleware: - metrics| Metric | Type | Description |
|---|---|---|
wippy_http_requests_total | Counter | Total requests |
wippy_http_request_duration_seconds | Histogram | Request latency |
wippy_http_requests_in_flight | Gauge | Concurrent requests |
Endpoint Firewall {#endpoint_firewall}
Section titled “Endpoint Firewall {#endpoint_firewall}”Authorization based on matched endpoint. Requires actor from token_auth.
post_middleware: - endpoint_firewallpost_options: endpoint_firewall.action: "access"| Option | Default | Description |
|---|---|---|
endpoint_firewall.action | access | Permission action to check |
Returns 401 Unauthorized (no actor) or 403 Forbidden (permission denied).
Resource Firewall {#resource_firewall}
Section titled “Resource Firewall {#resource_firewall}”Protect specific resources by ID. Useful at router level.
post_middleware: - resource_firewallpost_options: resource_firewall.action: "admin" resource_firewall.target: "app:admin-panel"| Option | Default | Description |
|---|---|---|
resource_firewall.action | access | Permission action |
resource_firewall.target | required | Resource registry ID |
Sendfile {#sendfile}
Section titled “Sendfile {#sendfile}”Serve files via X-Sendfile header from handlers.
middleware: - sendfileoptions: sendfile.fs: "app:downloads"Handler sets headers to trigger file serving:
| Header | Description |
|---|---|
X-Sendfile | File path within filesystem |
X-File-Name | Download filename |
Supports range requests for resumable downloads.
WebSocket Relay {#websocket_relay}
Section titled “WebSocket Relay {#websocket_relay}”Relay WebSocket connections to processes. See WebSocket Relay.
post_middleware: - websocket_relaypost_options: wsrelay.allowed.origins: "https://app.example.com"SSE Relay {#sse_relay}
Section titled “SSE Relay {#sse_relay}”Stream Server-Sent Events from processes. See Server-Sent Events.
post_middleware: - sse_relaypost_options: sserelay.allowed.origins: "https://app.example.com"OpenTelemetry {#otel}
Section titled “OpenTelemetry {#otel}”Records OpenTelemetry spans and metrics for incoming requests. Registered automatically when OTel is enabled; acts as a no-op otherwise.
middleware: - otelTakes no options. Works alongside the metrics middleware; enable both when you need Prometheus counters and OTel traces.
Middleware Order
Section titled “Middleware Order”Middleware executes in listed order. Recommended sequence:
middleware: - real_ip # 1. Extract real IP first - cors # 2. Handle CORS preflight - compress # 3. Set up response compression - ratelimit # 4. Check rate limits - metrics # 5. Record metrics - token_auth # 6. Authenticate requests
post_middleware: - endpoint_firewall # Authorize after route matchSee Also
Section titled “See Also”- Routing - Router configuration
- Security - Token stores and policies
- WebSocket Relay - WebSocket handling
- Server-Sent Events - SSE streaming
- Terminal - Terminal service