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}