static_web_server/
custom_headers.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// This file is part of Static Web Server.
3// See https://static-web-server.net/ for more information
4// Copyright (C) 2019-present Jose Quintana <joseluisq.net>
5
6//! Module to append custom HTTP headers via TOML config file.
7//!
8
9use hyper::{Body, Request, Response};
10use std::{ffi::OsStr, path::PathBuf};
11
12use crate::{handler::RequestHandlerOpts, settings::Headers, Error};
13
14/// Appends custom HTTP headers to a response if necessary
15pub(crate) fn post_process<T>(
16    opts: &RequestHandlerOpts,
17    req: &Request<T>,
18    mut resp: Response<Body>,
19    file_path: Option<&PathBuf>,
20) -> Result<Response<Body>, Error> {
21    if let Some(advanced) = &opts.advanced_opts {
22        append_headers(
23            req.uri().path(),
24            advanced.headers.as_deref(),
25            &mut resp,
26            file_path,
27        )
28    }
29    Ok(resp)
30}
31
32/// Append custom HTTP headers to current response.
33pub fn append_headers(
34    uri_path: &str,
35    headers_opts: Option<&[Headers]>,
36    resp: &mut Response<Body>,
37    file_path: Option<&PathBuf>,
38) {
39    if let Some(headers_vec) = headers_opts {
40        let mut uri_path_auto_index = None;
41        if file_path.is_some() && uri_path.ends_with('/') {
42            if let Some(name) = file_path.unwrap().file_name().and_then(OsStr::to_str) {
43                if uri_path == "/" {
44                    uri_path_auto_index = Some([uri_path, name].concat())
45                } else {
46                    uri_path_auto_index = Some([uri_path, "/", name].concat())
47                }
48            }
49        }
50
51        let uri_path = match uri_path_auto_index {
52            Some(ref s) => s.as_str(),
53            _ => uri_path,
54        };
55
56        for headers_entry in headers_vec {
57            // Match header glob pattern against request uri
58            if headers_entry.source.is_match(uri_path) {
59                // Add/update headers if uri matches
60                for (name, value) in &headers_entry.headers {
61                    resp.headers_mut().insert(name, value.to_owned());
62                }
63            }
64        }
65    }
66}