Merge pull request #502 from pyfisch/accesscontrolalloworigin
feat(headers): Allow `null` value in Access-Control-Allow-Origin
This commit is contained in:
		| @@ -1,11 +1,11 @@ | ||||
| use std::fmt; | ||||
| use std::fmt::{self, Display}; | ||||
| use std::str; | ||||
|  | ||||
| use url::Url; | ||||
| use header; | ||||
| use header::{Header, HeaderFormat}; | ||||
|  | ||||
| /// The `Access-Control-Allow-Origin` response header, | ||||
| /// part of [CORS](www.w3.org/TR/cors/#access-control-allow-origin-response-header) | ||||
| /// part of [CORS](http://www.w3.org/TR/cors/#access-control-allow-origin-response-header) | ||||
| /// | ||||
| /// The `Access-Control-Allow-Origin` header indicates whether a resource | ||||
| /// can be shared based by returning the value of the Origin request header, | ||||
| @@ -15,45 +15,60 @@ use header; | ||||
| /// ```plain | ||||
| /// Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*" | ||||
| /// ``` | ||||
| // FIXME: The documentation says differently (missing "null" value, "*" not used in practice, | ||||
| // orgin list no list but single value) | ||||
| /// | ||||
| /// # Example values | ||||
| /// * `null` | ||||
| /// * `*` | ||||
| /// * `http://google.com/` | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub enum AccessControlAllowOrigin { | ||||
|     /// Allow all origins | ||||
|     Any, | ||||
|     /// A hidden origin | ||||
|     Null, | ||||
|     /// Allow one particular origin | ||||
|     Value(Url), | ||||
| } | ||||
|  | ||||
| impl header::Header for AccessControlAllowOrigin { | ||||
| impl Header for AccessControlAllowOrigin { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Access-Control-Allow-Origin" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> { | ||||
|         if raw.len() == 1 { | ||||
|             match str::from_utf8(unsafe { &raw.get_unchecked(0)[..] }) { | ||||
|                 Ok(s) => { | ||||
|                     if s == "*" { | ||||
|                         Some(AccessControlAllowOrigin::Any) | ||||
|                     } else { | ||||
|                         Url::parse(s).ok().map( | ||||
|                             |url| AccessControlAllowOrigin::Value(url)) | ||||
|                     } | ||||
|                 }, | ||||
|                 _ => return None, | ||||
|             match unsafe { &raw.get_unchecked(0)[..] } { | ||||
|                 b"*" => Some(AccessControlAllowOrigin::Any), | ||||
|                 b"null" => Some(AccessControlAllowOrigin::Null), | ||||
|                 r => if let Ok(s) = str::from_utf8(r) { | ||||
|                     Url::parse(s).ok().map(|url| AccessControlAllowOrigin::Value(url)) | ||||
|                 } else { None } | ||||
|             } | ||||
|         } else { | ||||
|             return None; | ||||
|         } else { None } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for AccessControlAllowOrigin { | ||||
|     fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match *self { | ||||
|             AccessControlAllowOrigin::Any => f.write_str("*"), | ||||
|             AccessControlAllowOrigin::Null => f.write_str("null"), | ||||
|             AccessControlAllowOrigin::Value(ref url) => Display::fmt(url, f), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl header::HeaderFormat for AccessControlAllowOrigin { | ||||
|     fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match *self { | ||||
|             AccessControlAllowOrigin::Any => f.write_str("*"), | ||||
|             AccessControlAllowOrigin::Value(ref url) => fmt::Display::fmt(url, f) | ||||
|         } | ||||
| impl Display for AccessControlAllowOrigin { | ||||
|     fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||||
|         self.fmt_header(f) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod test_access_control_allow_orgin { | ||||
|     use header::*; | ||||
|     use super::AccessControlAllowOrigin as HeaderField; | ||||
|     test_header!(test1, vec![b"null"]); | ||||
|     test_header!(test2, vec![b"*"]); | ||||
|     test_header!(test3, vec![b"http://google.com/"]); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user