cogo_http/header/common/
access_control_allow_credentials.rs

1use std::fmt::{self, Display};
2use std::str;
3use unicase::UniCase;
4use crate::header::{Header, HeaderFormat};
5
6/// `Access-Control-Allow-Credentials` header, part of
7/// [CORS](http://www.w3.org/TR/cors/#access-control-allow-headers-response-header)
8///
9/// > The Access-Control-Allow-Credentials HTTP response header indicates whether the
10/// > response to request can be exposed when the credentials flag is true. When part
11/// > of the response to an preflight request it indicates that the actual request can
12/// > be made with credentials. The Access-Control-Allow-Credentials HTTP header must
13/// > match the following ABNF:
14///
15/// # ABNF
16/// ```plain
17/// Access-Control-Allow-Credentials: "Access-Control-Allow-Credentials" ":" "true"
18/// ```
19///
20/// Since there is only one acceptable field value, the header struct does not accept
21/// any values at all. Setting an empty `AccessControlAllowCredentials` header is
22/// sufficient. See the examples below.
23///
24/// # Example values
25/// * "true"
26///
27/// # Examples
28/// ```
29/// # extern crate cogo_http;
30/// # fn main() {
31///
32/// use cogo_http::header::{Headers, AccessControlAllowCredentials};
33///
34/// let mut headers = Headers::new();
35/// headers.set(AccessControlAllowCredentials);
36/// # }
37/// ```
38#[derive(Clone, PartialEq, Debug)]
39pub struct AccessControlAllowCredentials;
40
41const ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE: UniCase<&'static str> = UniCase("true");
42
43impl Header for AccessControlAllowCredentials {
44    fn header_name() -> &'static str {
45        "Access-Control-Allow-Credentials"
46    }
47
48    fn parse_header(raw: &[Vec<u8>]) -> crate::Result<AccessControlAllowCredentials> {
49        if raw.len() == 1 {
50            let text = unsafe {
51                // safe because:
52                // 1. we just checked raw.len == 1
53                // 2. we don't actually care if it's utf8, we just want to
54                //    compare the bytes with the "case" normalized. If it's not
55                //    utf8, then the byte comparison will fail, and we'll return
56                //    None. No big deal.
57                str::from_utf8_unchecked(raw.get_unchecked(0))
58            };
59            if UniCase(text) == ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE {
60                return Ok(AccessControlAllowCredentials);
61            }
62        }
63        Err(crate::Error::Header)
64    }
65}
66
67impl HeaderFormat for AccessControlAllowCredentials {
68    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        f.write_str("true")
70    }
71}
72
73impl Display for AccessControlAllowCredentials {
74    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
75        self.fmt_header(f)
76    }
77}
78
79#[cfg(test)]
80mod test_access_control_allow_credentials {
81    use std::str;
82    use crate::header::*;
83    use super::AccessControlAllowCredentials as HeaderField;
84    test_header!(works,        vec![b"true"], Some(HeaderField));
85    test_header!(ignores_case, vec![b"True"]);
86    test_header!(not_bool,     vec![b"false"], None);
87    test_header!(only_single,  vec![b"true", b"true"], None);
88    test_header!(no_gibberish, vec!["\u{645}\u{631}\u{62d}\u{628}\u{627}".as_bytes()], None);
89}