static_web_server/
security_headers.rs1use http::header::{
10 CONTENT_SECURITY_POLICY, STRICT_TRANSPORT_SECURITY, X_CONTENT_TYPE_OPTIONS, X_FRAME_OPTIONS,
11};
12use hyper::{Body, Request, Response, header::HeaderValue};
13
14use crate::{Error, handler::RequestHandlerOpts};
15
16static HSTS_VALUE: HeaderValue =
18 HeaderValue::from_static("max-age=63072000; includeSubDomains; preload");
19static XFO_VALUE: HeaderValue = HeaderValue::from_static("DENY");
20static XCTO_VALUE: HeaderValue = HeaderValue::from_static("nosniff");
21static CSP_VALUE: HeaderValue = HeaderValue::from_static("frame-ancestors 'self'");
22
23pub(crate) fn init(enabled: bool, handler_opts: &mut RequestHandlerOpts) {
24 handler_opts.security_headers = enabled;
25 tracing::info!("security headers: enabled={enabled}");
26}
27
28pub(crate) fn post_process<T>(
30 opts: &RequestHandlerOpts,
31 _req: &Request<T>,
32 mut resp: Response<Body>,
33) -> Result<Response<Body>, Error> {
34 if opts.security_headers {
35 append_headers(&mut resp);
36 }
37 Ok(resp)
38}
39
40pub fn append_headers(resp: &mut Response<Body>) {
43 resp.headers_mut()
45 .insert(STRICT_TRANSPORT_SECURITY, HSTS_VALUE.clone());
46
47 resp.headers_mut()
49 .insert(X_FRAME_OPTIONS, XFO_VALUE.clone());
50
51 resp.headers_mut()
53 .insert(X_CONTENT_TYPE_OPTIONS, XCTO_VALUE.clone());
54
55 resp.headers_mut()
57 .insert(CONTENT_SECURITY_POLICY, CSP_VALUE.clone());
58}