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 std::str;
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use header;
|
use header::{Header, HeaderFormat};
|
||||||
|
|
||||||
/// The `Access-Control-Allow-Origin` response header,
|
/// 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
|
/// The `Access-Control-Allow-Origin` header indicates whether a resource
|
||||||
/// can be shared based by returning the value of the Origin request header,
|
/// can be shared based by returning the value of the Origin request header,
|
||||||
@@ -15,45 +15,60 @@ use header;
|
|||||||
/// ```plain
|
/// ```plain
|
||||||
/// Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" origin-list-or-null | "*"
|
/// 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)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum AccessControlAllowOrigin {
|
pub enum AccessControlAllowOrigin {
|
||||||
/// Allow all origins
|
/// Allow all origins
|
||||||
Any,
|
Any,
|
||||||
|
/// A hidden origin
|
||||||
|
Null,
|
||||||
/// Allow one particular origin
|
/// Allow one particular origin
|
||||||
Value(Url),
|
Value(Url),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl header::Header for AccessControlAllowOrigin {
|
impl Header for AccessControlAllowOrigin {
|
||||||
fn header_name() -> &'static str {
|
fn header_name() -> &'static str {
|
||||||
"Access-Control-Allow-Origin"
|
"Access-Control-Allow-Origin"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> {
|
fn parse_header(raw: &[Vec<u8>]) -> Option<AccessControlAllowOrigin> {
|
||||||
if raw.len() == 1 {
|
if raw.len() == 1 {
|
||||||
match str::from_utf8(unsafe { &raw.get_unchecked(0)[..] }) {
|
match unsafe { &raw.get_unchecked(0)[..] } {
|
||||||
Ok(s) => {
|
b"*" => Some(AccessControlAllowOrigin::Any),
|
||||||
if s == "*" {
|
b"null" => Some(AccessControlAllowOrigin::Null),
|
||||||
Some(AccessControlAllowOrigin::Any)
|
r => if let Ok(s) = str::from_utf8(r) {
|
||||||
} else {
|
Url::parse(s).ok().map(|url| AccessControlAllowOrigin::Value(url))
|
||||||
Url::parse(s).ok().map(
|
} else { None }
|
||||||
|url| AccessControlAllowOrigin::Value(url))
|
|
||||||
}
|
}
|
||||||
},
|
} else { None }
|
||||||
_ => return None,
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
return 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 {
|
impl Display for AccessControlAllowOrigin {
|
||||||
fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||||
match *self {
|
self.fmt_header(f)
|
||||||
AccessControlAllowOrigin::Any => f.write_str("*"),
|
|
||||||
AccessControlAllowOrigin::Value(ref url) => fmt::Display::fmt(url, 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