Host Validation & Cache-Control
Host Validation (Allowed Hosts)
How it works
- Compares the request
Hostheader against the list of allowed hosts - Blocks requests with a non-allowed host (HTTP 400)
- Protects against Host Header Injection attacks
HTTP/2 and the Host header
HTTP/2 does not send a Host header — it uses the :authority pseudo-header instead.
Runique handles this automatically: if the Host header is absent, the middleware
reads the authority from request.uri().authority().
This covers direct HTTP/1.1, HTTP/2 (e.g. ACME or Cloudflare), and reverse proxies that proxy over HTTP/2.
Logging
Rejections can be logged via RuniqueLog:
.with_log(|l| l.host_validation(Level::WARN))
In production, WARN is recommended to detect attacks or misconfigurations.
Configuration via the builder
Host validation is configured in main.rs via the builder — there is no environment variable for this:
.middleware(|m| {
m.with_allowed_hosts(|h| {
h.enabled(!is_debug())
.host("example.com")
.host(".example.com") // matches example.com AND all its subdomains
})
})
Supported patterns
"localhost"— exact match".example.com"— matchesexample.comand*.example.com"*"— all hosts (⚠️ dangerous in production)
Debug mode
In DEBUG=true, typically use .enabled(!is_debug()) to disable validation during development.
Cache-Control
Development mode (DEBUG=true)
no-cache headers are added to force reloads:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Production mode (DEBUG=false)
Caching headers are enabled for performance.