tower_http/set_header/
mod.rs

1//! Middleware for setting headers on requests and responses.
2//!
3//! See [request] and [response] for more details.
4
5use http::{header::HeaderName, HeaderMap, HeaderValue, Request, Response};
6
7pub mod request;
8pub mod response;
9
10#[doc(inline)]
11pub use self::{
12    request::{SetRequestHeader, SetRequestHeaderLayer},
13    response::{SetResponseHeader, SetResponseHeaderLayer},
14};
15
16/// Trait for producing header values.
17///
18/// Used by [`SetRequestHeader`] and [`SetResponseHeader`].
19///
20/// This trait is implemented for closures with the correct type signature. Typically users will
21/// not have to implement this trait for their own types.
22///
23/// It is also implemented directly for [`HeaderValue`]. When a fixed header value should be added
24/// to all responses, it can be supplied directly to the middleware.
25pub trait MakeHeaderValue<T> {
26    /// Try to create a header value from the request or response.
27    fn make_header_value(&mut self, message: &T) -> Option<HeaderValue>;
28}
29
30impl<F, T> MakeHeaderValue<T> for F
31where
32    F: FnMut(&T) -> Option<HeaderValue>,
33{
34    fn make_header_value(&mut self, message: &T) -> Option<HeaderValue> {
35        self(message)
36    }
37}
38
39impl<T> MakeHeaderValue<T> for HeaderValue {
40    fn make_header_value(&mut self, _message: &T) -> Option<HeaderValue> {
41        Some(self.clone())
42    }
43}
44
45impl<T> MakeHeaderValue<T> for Option<HeaderValue> {
46    fn make_header_value(&mut self, _message: &T) -> Option<HeaderValue> {
47        self.clone()
48    }
49}
50
51#[derive(Debug, Clone, Copy)]
52enum InsertHeaderMode {
53    Override,
54    Append,
55    IfNotPresent,
56}
57
58impl InsertHeaderMode {
59    fn apply<T, M>(self, header_name: &HeaderName, target: &mut T, make: &mut M)
60    where
61        T: Headers,
62        M: MakeHeaderValue<T>,
63    {
64        match self {
65            InsertHeaderMode::Override => {
66                if let Some(value) = make.make_header_value(target) {
67                    target.headers_mut().insert(header_name.clone(), value);
68                }
69            }
70            InsertHeaderMode::IfNotPresent => {
71                if !target.headers().contains_key(header_name) {
72                    if let Some(value) = make.make_header_value(target) {
73                        target.headers_mut().insert(header_name.clone(), value);
74                    }
75                }
76            }
77            InsertHeaderMode::Append => {
78                if let Some(value) = make.make_header_value(target) {
79                    target.headers_mut().append(header_name.clone(), value);
80                }
81            }
82        }
83    }
84}
85
86trait Headers {
87    fn headers(&self) -> &HeaderMap;
88
89    fn headers_mut(&mut self) -> &mut HeaderMap;
90}
91
92impl<B> Headers for Request<B> {
93    fn headers(&self) -> &HeaderMap {
94        Request::headers(self)
95    }
96
97    fn headers_mut(&mut self) -> &mut HeaderMap {
98        Request::headers_mut(self)
99    }
100}
101
102impl<B> Headers for Response<B> {
103    fn headers(&self) -> &HeaderMap {
104        Response::headers(self)
105    }
106
107    fn headers_mut(&mut self) -> &mut HeaderMap {
108        Response::headers_mut(self)
109    }
110}