Expand description
The HTTPS enforcement gate: the reference pipeline’s third check.
This is the Rust family’s port of
guard_core/core/checks/implementations/https_enforcement.py. One call,
decide, decides whether a request that reached the engine over plain
HTTP must be redirected to its https form:
route require_https set: the route verdict wins (Some(false) disables)
otherwise: the global enforce_https knob decides
not required: pass
request already https: pass
trusted-proxy upgrade: X-Forwarded-Proto: https counts as https, but
only when trust_x_forwarded_proto is on, the
trusted-proxy list is non-empty, the connecting
IP is on it, and the header is present
violation: Redirect (the reference's
create_https_redirect: a 301 to the https URL)§Details that mirror the reference exactly
- The route config’s
require_httpswins whenever a route config exists, even when it isfalse(the reference’sroute_config.require_https if route_config else enforce_https), so the route input isOption<bool>andSome(false)opts a route out of a globally enforced HTTPS. - The proxy-upgrade arm is the reference
_is_request_https: the header alone never decides - a forgedX-Forwarded-Protofrom a client the deployment does not trust is ignored, exactly as in the reference. The header comparison is case-insensitive on the value (forwarded.lower() == "https"); a bare-IP proxy entry compares exactly, a CIDR entry parses the connecting address (the reference raises on an unparseable address into the pipeline’s error handling; this port reads an unparseable address as not trusted, which keeps the seam total). - The verdict never says what to send: the reference’s redirect comes
from the response factory (
301,Location= the request URL with the scheme replaced byhttps, then the response modifier). The stage that wires this seam composes the target URL - the engine only decides that the request must go there.
§Example
use guard_core_engine::https_enforcement::{decide, HttpsEnforcementConfig, HttpsRequest, HttpsVerdict};
let config = HttpsEnforcementConfig::new(true, false, Vec::<String>::new()).expect("valid");
// Plain HTTP under a global enforcement is a redirect.
let request = HttpsRequest { url_scheme: "http", client_host: None, x_forwarded_proto: None, route_require_https: None };
assert!(matches!(decide(&request, &config), HttpsVerdict::Redirect { .. }));
// HTTPS passes, and a route can opt out of the global arm.
let request = HttpsRequest { url_scheme: "https", client_host: None, x_forwarded_proto: None, route_require_https: None };
assert_eq!(decide(&request, &config), HttpsVerdict::Allowed);
let request = HttpsRequest { url_scheme: "http", client_host: None, x_forwarded_proto: None, route_require_https: Some(false) };
assert_eq!(decide(&request, &config), HttpsVerdict::Allowed);Structs§
- Https
Enforcement Config - The enforcement knobs (
SecurityConfig.enforce_https,.trust_x_forwarded_proto,.trusted_proxies). - Https
Request - The request facts the decision reads (
request.url_scheme,request.client_host, theX-Forwarded-Protoheader, and the route config’srequire_httpswhen a route config exists).
Enums§
- Https
Verdict - What
decidedecided.
Constants§
- HTTPS_
ENFORCEMENT_ CHECK_ NAME - The check’s stable name (
check_name). - HTTPS_
REDIRECT_ STATUS - The redirect status the reference’s
create_https_redirectanswers with (create_redirect_response(https_url, 301)).
Functions§
- decide
- The reference check body: the route’s
require_httpswins when a route config exists, else the global knob; a required plain-HTTP request is a redirect verdict.