use axum::http::HeaderValue;
use axum::Router;
use tower_http::set_header::SetResponseHeaderLayer;
use crate::config::SecurityHeadersConfig;
pub fn apply_security_headers(
mut app: Router,
config: &SecurityHeadersConfig,
tls_enabled: bool,
) -> Router {
if !config.enabled {
return app;
}
if tls_enabled && config.hsts {
let mut value = format!("max-age={}", config.hsts_max_age_secs);
if config.hsts_include_subdomains {
value.push_str("; includeSubDomains");
}
if config.hsts_preload {
value.push_str("; preload");
}
if let Ok(hv) = HeaderValue::from_str(&value) {
app = app.layer(SetResponseHeaderLayer::overriding(
http::header::STRICT_TRANSPORT_SECURITY,
hv,
));
}
}
if config.x_content_type_options {
app = app.layer(SetResponseHeaderLayer::if_not_present(
http::header::X_CONTENT_TYPE_OPTIONS,
HeaderValue::from_static("nosniff"),
));
}
if !config.x_frame_options.is_empty() {
if let Ok(hv) = HeaderValue::from_str(&config.x_frame_options) {
app = app.layer(SetResponseHeaderLayer::if_not_present(
http::header::X_FRAME_OPTIONS,
hv,
));
}
}
if config.x_xss_protection {
app = app.layer(SetResponseHeaderLayer::if_not_present(
http::header::X_XSS_PROTECTION,
HeaderValue::from_static("0"),
));
}
if !config.referrer_policy.is_empty() {
if let Ok(hv) = HeaderValue::from_str(&config.referrer_policy) {
app = app.layer(SetResponseHeaderLayer::if_not_present(
http::header::REFERRER_POLICY,
hv,
));
}
}
if let Some(ref policy) = config.permissions_policy {
if let Ok(hv) = HeaderValue::from_str(policy) {
app = app.layer(SetResponseHeaderLayer::if_not_present(
http::header::HeaderName::from_static("permissions-policy"),
hv,
));
}
}
app
}