Skip to main content

rama_http_headers/common/
access_control_request_private_network.rs

1use rama_http_types::{HeaderName, HeaderValue};
2
3use crate::{Error, HeaderDecode, HeaderEncode, TypedHeader};
4
5/// `Access-Control-Request-Private-Network` header, as documented in
6/// [this draft of WICG](https://wicg.github.io/private-network-access/).
7///
8/// Not an official standard but widely used.
9/// This CORS header to allow a public origin make a cross site request
10/// to a server hosted on a private network (e.g. behind a firewall).
11///
12/// # ABNF
13///
14/// ```text
15/// Access-Control-Request-Private-Network: "Access-Control-Request-Private-Network" ":" "true"
16/// ```
17///
18/// Since there is only one acceptable field value, the header struct does not accept
19/// any values at all. Setting an empty `AccessControlRequestPrivateNetwork` header is
20/// sufficient. See the examples below.
21///
22/// # Example values
23/// * "true"
24///
25/// # Examples
26///
27/// ```
28/// use rama_http_headers::AccessControlRequestPrivateNetwork;
29///
30/// let allow_creds = AccessControlRequestPrivateNetwork::default();
31/// ```
32#[derive(Default, Clone, PartialEq, Eq, Debug)]
33#[non_exhaustive]
34pub struct AccessControlRequestPrivateNetwork;
35
36impl AccessControlRequestPrivateNetwork {
37    #[must_use]
38    pub fn new() -> Self {
39        Self
40    }
41}
42
43impl TypedHeader for AccessControlRequestPrivateNetwork {
44    fn name() -> &'static HeaderName {
45        &::rama_http_types::header::ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK
46    }
47}
48
49impl HeaderDecode for AccessControlRequestPrivateNetwork {
50    fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
51        values
52            .next()
53            .and_then(|value| if value == "true" { Some(Self) } else { None })
54            .ok_or_else(Error::invalid)
55    }
56}
57
58impl HeaderEncode for AccessControlRequestPrivateNetwork {
59    fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
60        values.extend(::std::iter::once(HeaderValue::from_static("true")));
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::super::test_decode;
67    use super::*;
68
69    #[test]
70    fn allow_private_network_is_case_sensitive() {
71        let allow_header = test_decode::<AccessControlRequestPrivateNetwork>(&["true"]);
72        assert!(allow_header.is_some());
73
74        let allow_header = test_decode::<AccessControlRequestPrivateNetwork>(&["True"]);
75        assert!(allow_header.is_none());
76    }
77}