cogo_http/header/common/
access_control_allow_origin.rs

1use std::fmt::{self, Display};
2
3use crate::header::{Header, HeaderFormat};
4
5/// The `Access-Control-Allow-Origin` response header,
6/// part of [CORS](http://www.w3.org/TR/cors/#access-control-allow-origin-response-header)
7///
8/// The `Access-Control-Allow-Origin` header indicates whether a resource
9/// can be shared based by returning the value of the Origin request header,
10/// "*", or "null" in the response.
11///
12/// # ABNF
13/// ```plain
14/// Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"
15/// ```
16///
17/// # Example values
18/// * `null`
19/// * `*`
20/// * `http://google.com/`
21///
22/// # Examples
23/// ```
24/// use cogo_http::header::{Headers, AccessControlAllowOrigin};
25///
26/// let mut headers = Headers::new();
27/// headers.set(
28///     AccessControlAllowOrigin::Any
29/// );
30/// ```
31/// ```
32/// use cogo_http::header::{Headers, AccessControlAllowOrigin};
33///
34/// let mut headers = Headers::new();
35/// headers.set(
36///     AccessControlAllowOrigin::Null,
37/// );
38/// ```
39/// ```
40/// use cogo_http::header::{Headers, AccessControlAllowOrigin};
41///
42/// let mut headers = Headers::new();
43/// headers.set(
44///     AccessControlAllowOrigin::Value("http://hyper.rs".to_owned())
45/// );
46/// ```
47#[derive(Clone, PartialEq, Debug)]
48pub enum AccessControlAllowOrigin {
49    /// Allow all origins
50    Any,
51    /// A hidden origin
52    Null,
53    /// Allow one particular origin
54    Value(String),
55}
56
57impl Header for AccessControlAllowOrigin {
58    fn header_name() -> &'static str {
59        "Access-Control-Allow-Origin"
60    }
61
62    fn parse_header(raw: &[Vec<u8>]) -> crate::Result<AccessControlAllowOrigin> {
63        if raw.len() != 1 {
64            return Err(crate::Error::Header)
65        }
66        let value = unsafe { raw.get_unchecked(0) };
67        Ok(match &value[..] {
68            b"*" => AccessControlAllowOrigin::Any,
69            b"null" => AccessControlAllowOrigin::Null,
70            _ => AccessControlAllowOrigin::Value(r#try!(String::from_utf8(value.clone())))
71        })
72    }
73}
74
75impl HeaderFormat for AccessControlAllowOrigin {
76    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        match *self {
78            AccessControlAllowOrigin::Any => f.write_str("*"),
79            AccessControlAllowOrigin::Null => f.write_str("null"),
80            AccessControlAllowOrigin::Value(ref url) => Display::fmt(url, f),
81        }
82    }
83}
84
85impl Display for AccessControlAllowOrigin {
86    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
87        self.fmt_header(f)
88    }
89}
90
91#[cfg(test)]
92mod test_access_control_allow_orgin {
93    use crate::header::*;
94    use super::AccessControlAllowOrigin as HeaderField;
95    test_header!(test1, vec![b"null"]);
96    test_header!(test2, vec![b"*"]);
97    test_header!(test3, vec![b"http://google.com/"]);
98}