Skip to main content

rama_http_headers/common/
access_control_allow_headers.rs

1use rama_http_types::HeaderName;
2
3derive_values_or_any_header! {
4    #[header(name = ACCESS_CONTROL_ALLOW_HEADERS, sep = Comma)]
5    #[derive(Clone, Debug, PartialEq)]
6    /// `Access-Control-Allow-Headers` header, as defined on
7    /// [mdn](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Access-Control-Allow-Headers).
8    ///
9    /// The `Access-Control-Allow-Headers` header indicates, as part of the
10    /// response to a preflight request, which header field names can be used
11    /// during the actual request.
12    ///
13    /// # ABNF
14    ///
15    /// ```text
16    /// Access-Control-Allow-Headers: "Access-Control-Allow-Headers" ":" #field-name
17    /// ```
18    ///
19    /// # Example values
20    /// * `accept-language, date`
21    /// * `*` (any)
22    ///
23    /// # Examples
24    ///
25    /// ```
26    /// use rama_utils::collections::non_empty_vec;
27    /// use rama_http_types::header::{CACHE_CONTROL, CONTENT_TYPE};
28    /// use rama_http_headers::AccessControlAllowHeaders;
29    ///
30    /// let allow_headers = AccessControlAllowHeaders::new_values(
31    ///     non_empty_vec![CACHE_CONTROL, CONTENT_TYPE],
32    /// );
33    ///
34    /// let any_allow_headers = AccessControlAllowHeaders::new_any();
35    /// ```
36    pub struct AccessControlAllowHeaders(pub ValuesOrAny<HeaderName>);
37}
38
39#[cfg(test)]
40mod tests {
41    use super::super::{test_decode, test_encode};
42    use super::*;
43    use rama_utils::collections::non_empty_vec;
44
45    #[test]
46    fn decode_header_single() {
47        let allow_headers = test_decode::<AccessControlAllowHeaders>(&["foo, bar"])
48            .unwrap()
49            .into_values()
50            .unwrap();
51
52        assert_eq!(allow_headers.len(), 2);
53        assert_eq!(allow_headers[0], "foo");
54        assert_eq!(allow_headers[1], "bar");
55    }
56
57    #[test]
58    fn decode_any() {
59        assert!(
60            test_decode::<AccessControlAllowHeaders>(&["*"])
61                .unwrap()
62                .is_any(),
63        );
64    }
65
66    #[test]
67    fn decode_any_with_trailer_value() {
68        let allow_headers = test_decode::<AccessControlAllowHeaders>(&["*, bar"])
69            .unwrap()
70            .into_values()
71            .unwrap();
72
73        assert_eq!(allow_headers.len(), 2);
74        assert_eq!(allow_headers[0], "*");
75        assert_eq!(allow_headers[1], "bar");
76    }
77
78    #[test]
79    fn decode_any_with_trailer_header() {
80        let allow_headers = test_decode::<AccessControlAllowHeaders>(&["*", "bar"])
81            .unwrap()
82            .into_values()
83            .unwrap();
84
85        assert_eq!(allow_headers.len(), 2);
86        assert_eq!(allow_headers[0], "*");
87        assert_eq!(allow_headers[1], "bar");
88    }
89
90    #[test]
91    fn decode_header_multi() {
92        let allow_headers = test_decode::<AccessControlAllowHeaders>(&["foo, bar", "baz"])
93            .unwrap()
94            .into_values()
95            .unwrap();
96
97        assert_eq!(allow_headers.len(), 3);
98        assert_eq!(allow_headers[0], "foo");
99        assert_eq!(allow_headers[1], "bar");
100        assert_eq!(allow_headers[2], "baz");
101    }
102
103    #[test]
104    fn encode() {
105        let allow = AccessControlAllowHeaders::new_values(non_empty_vec![
106            ::rama_http_types::header::CACHE_CONTROL,
107            ::rama_http_types::header::IF_RANGE,
108        ]);
109
110        let headers = test_encode(allow);
111        assert_eq!(
112            headers["access-control-allow-headers"],
113            "cache-control, if-range"
114        );
115    }
116
117    #[test]
118    fn encode_any() {
119        let allow = AccessControlAllowHeaders::new_any();
120        let headers = test_encode(allow);
121        assert_eq!(headers["access-control-allow-headers"], "*");
122    }
123
124    #[test]
125    fn decode_with_empty_header_value() {
126        assert!(test_decode::<AccessControlAllowHeaders>(&[""]).is_none());
127    }
128
129    #[test]
130    fn decode_with_no_headers() {
131        assert!(test_decode::<AccessControlAllowHeaders>(&[]).is_none());
132    }
133
134    #[test]
135    fn decode_with_invalid_value_str() {
136        assert!(test_decode::<AccessControlAllowHeaders>(&["foo foo, bar"]).is_none());
137    }
138}