fn force_ssl_location(host: &str, uri: &Uri, port: u16) -> Option { 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 { 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 { 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) }