64 lines
2.0 KiB
Rust
64 lines
2.0 KiB
Rust
fn force_ssl_location(host: &str, uri: &Uri, port: u16) -> Option<HeaderValue> {
|
|
let path = uri
|
|
.path_and_query()
|
|
.map(|value| value.as_str())
|
|
.unwrap_or("/");
|
|
let location = if port == 443 {
|
|
format!("https://{host}{path}")
|
|
} else {
|
|
format!("https://{host}:{port}{path}")
|
|
};
|
|
HeaderValue::from_str(&location).ok()
|
|
}
|
|
|
|
fn canonical_host_redirect(
|
|
frontend: &crate::config::CompiledFrontend,
|
|
host: &str,
|
|
tls: bool,
|
|
local_port: u16,
|
|
uri: &Uri,
|
|
) -> Option<Response> {
|
|
let (from, to) = frontend.www_redirect.as_ref()?;
|
|
if !host.eq_ignore_ascii_case(from) {
|
|
return None;
|
|
}
|
|
let (scheme, port) = if tls {
|
|
("https", local_port)
|
|
} else if frontend.force_ssl {
|
|
("https", frontend.https_redirect_port?)
|
|
} else {
|
|
("http", local_port)
|
|
};
|
|
let path = uri.path_and_query().map(|value| value.as_str()).unwrap_or("/");
|
|
let default_port = (scheme == "https" && port == 443) || (scheme == "http" && port == 80);
|
|
let location = if default_port {
|
|
format!("{scheme}://{to}{path}")
|
|
} else {
|
|
format!("{scheme}://{to}:{port}{path}")
|
|
};
|
|
let mut response = StatusCode::PERMANENT_REDIRECT.into_response();
|
|
response.headers_mut().insert(http::header::LOCATION, HeaderValue::from_str(&location).ok()?);
|
|
response.headers_mut().insert("cache-control", HeaderValue::from_static("no-store"));
|
|
Some(response)
|
|
}
|
|
|
|
fn force_ssl_redirect(
|
|
frontend: &crate::config::CompiledFrontend,
|
|
host: &str,
|
|
uri: &Uri,
|
|
) -> Option<Response> {
|
|
if !frontend.force_ssl {
|
|
return None;
|
|
}
|
|
let location = force_ssl_location(host, uri, frontend.https_redirect_port?)?;
|
|
let mut response = StatusCode::PERMANENT_REDIRECT.into_response();
|
|
response
|
|
.headers_mut()
|
|
.insert(http::header::LOCATION, location);
|
|
response
|
|
.headers_mut()
|
|
.insert("cache-control", HeaderValue::from_static("no-store"));
|
|
Some(response)
|
|
}
|
|
|