Fix bug where Access-Control-Allow-Origin included a trailing `/`
Which broke all browsers
This commit is contained in:
parent
87e4145493
commit
0163ff6a26
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rocket_cors"
|
name = "rocket_cors"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
authors = ["Yong Wen Chua <me@yongwen.xyz>"]
|
authors = ["Yong Wen Chua <me@yongwen.xyz>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
|
@ -29,7 +29,7 @@ might work, but it's not guaranteed.
|
||||||
Add the following to Cargo.toml:
|
Add the following to Cargo.toml:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
rocket_cors = "0.1.3"
|
rocket_cors = "0.1.4"
|
||||||
```
|
```
|
||||||
|
|
||||||
To use the latest `master` branch, for example:
|
To use the latest `master` branch, for example:
|
||||||
|
|
38
src/lib.rs
38
src/lib.rs
|
@ -27,7 +27,7 @@
|
||||||
//! Add the following to Cargo.toml:
|
//! Add the following to Cargo.toml:
|
||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! rocket_cors = "0.1.3"
|
//! rocket_cors = "0.1.4"
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! To use the latest `master` branch, for example:
|
//! To use the latest `master` branch, for example:
|
||||||
|
@ -865,7 +865,7 @@ impl Cors {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
allow_origin: Option<AllOrSome<String>>,
|
allow_origin: Option<AllOrSome<Url>>,
|
||||||
allow_methods: HashSet<Method>,
|
allow_methods: HashSet<Method>,
|
||||||
allow_headers: HeaderFieldNamesSet,
|
allow_headers: HeaderFieldNamesSet,
|
||||||
allow_credentials: bool,
|
allow_credentials: bool,
|
||||||
|
@ -889,8 +889,8 @@ impl Response {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes the `Response` and return an altered response with origin and `vary_origin` set
|
/// Consumes the `Response` and return an altered response with origin and `vary_origin` set
|
||||||
fn origin(mut self, origin: &str, vary_origin: bool) -> Self {
|
fn origin(mut self, origin: &Url, vary_origin: bool) -> Self {
|
||||||
self.allow_origin = Some(AllOrSome::Some(origin.to_string()));
|
self.allow_origin = Some(AllOrSome::Some(origin.clone()));
|
||||||
self.vary_origin = vary_origin;
|
self.vary_origin = vary_origin;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -966,7 +966,7 @@ impl Response {
|
||||||
|
|
||||||
let origin = match *origin {
|
let origin = match *origin {
|
||||||
AllOrSome::All => "*".to_string(),
|
AllOrSome::All => "*".to_string(),
|
||||||
AllOrSome::Some(ref origin) => origin.to_string(),
|
AllOrSome::Some(ref origin) => origin.origin().unicode_serialization(),
|
||||||
};
|
};
|
||||||
|
|
||||||
response.set_raw_header("Access-Control-Allow-Origin", origin);
|
response.set_raw_header("Access-Control-Allow-Origin", origin);
|
||||||
|
@ -1345,10 +1345,10 @@ fn preflight_response(
|
||||||
if options.send_wildcard {
|
if options.send_wildcard {
|
||||||
response.any()
|
response.any()
|
||||||
} else {
|
} else {
|
||||||
response.origin(origin.as_str(), true)
|
response.origin(&origin, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AllOrSome::Some(_) => response.origin(origin.as_str(), false),
|
AllOrSome::Some(_) => response.origin(&origin, false),
|
||||||
};
|
};
|
||||||
let response = response.credentials(options.allow_credentials);
|
let response = response.credentials(options.allow_credentials);
|
||||||
|
|
||||||
|
@ -1434,10 +1434,10 @@ fn actual_request_response(options: &Cors, origin: Origin) -> Response {
|
||||||
if options.send_wildcard {
|
if options.send_wildcard {
|
||||||
response.any()
|
response.any()
|
||||||
} else {
|
} else {
|
||||||
response.origin(origin.as_str(), true)
|
response.origin(&origin, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AllOrSome::Some(_) => response.origin(origin.as_str(), false),
|
AllOrSome::Some(_) => response.origin(&origin, false),
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = response.credentials(options.allow_credentials);
|
let response = response.credentials(options.allow_credentials);
|
||||||
|
@ -1564,7 +1564,8 @@ mod tests {
|
||||||
fn response_sets_exposed_headers_correctly() {
|
fn response_sets_exposed_headers_correctly() {
|
||||||
let headers = vec!["Bar", "Baz", "Foo"];
|
let headers = vec!["Bar", "Baz", "Foo"];
|
||||||
let response = Response::new();
|
let response = Response::new();
|
||||||
let response = response.origin("https://www.example.com", false);
|
let response =
|
||||||
|
response.origin(&FromStr::from_str("https://www.example.com").unwrap(), false);
|
||||||
let response = response.exposed_headers(&headers);
|
let response = response.exposed_headers(&headers);
|
||||||
|
|
||||||
// Build response and check built response header
|
// Build response and check built response header
|
||||||
|
@ -1586,7 +1587,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn response_sets_max_age_correctly() {
|
fn response_sets_max_age_correctly() {
|
||||||
let response = Response::new();
|
let response = Response::new();
|
||||||
let response = response.origin("https://www.example.com", false);
|
let response =
|
||||||
|
response.origin(&FromStr::from_str("https://www.example.com").unwrap(), false);
|
||||||
|
|
||||||
let response = response.max_age(Some(42));
|
let response = response.max_age(Some(42));
|
||||||
|
|
||||||
|
@ -1600,7 +1602,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn response_does_not_set_max_age_when_none() {
|
fn response_does_not_set_max_age_when_none() {
|
||||||
let response = Response::new();
|
let response = Response::new();
|
||||||
let response = response.origin("https://www.example.com", false);
|
let response =
|
||||||
|
response.origin(&FromStr::from_str("https://www.example.com").unwrap(), false);
|
||||||
|
|
||||||
let response = response.max_age(None);
|
let response = response.max_age(None);
|
||||||
|
|
||||||
|
@ -1714,7 +1717,8 @@ mod tests {
|
||||||
.finalize();
|
.finalize();
|
||||||
|
|
||||||
let response = Response::new();
|
let response = Response::new();
|
||||||
let response = response.origin("https://www.example.com", false);
|
let response =
|
||||||
|
response.origin(&FromStr::from_str("https://www.example.com").unwrap(), false);
|
||||||
let response = response.response(original);
|
let response = response.response(original);
|
||||||
// Check CORS header
|
// Check CORS header
|
||||||
let expected_header = vec!["https://www.example.com"];
|
let expected_header = vec!["https://www.example.com"];
|
||||||
|
@ -2058,7 +2062,7 @@ mod tests {
|
||||||
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
||||||
|
|
||||||
let expected_response = Response::new()
|
let expected_response = Response::new()
|
||||||
.origin("https://www.acme.com/", false)
|
.origin(&FromStr::from_str("https://www.acme.com/").unwrap(), false)
|
||||||
.headers(&["Authorization"])
|
.headers(&["Authorization"])
|
||||||
.methods(&options.allowed_methods)
|
.methods(&options.allowed_methods)
|
||||||
.credentials(options.allow_credentials)
|
.credentials(options.allow_credentials)
|
||||||
|
@ -2097,7 +2101,7 @@ mod tests {
|
||||||
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
||||||
|
|
||||||
let expected_response = Response::new()
|
let expected_response = Response::new()
|
||||||
.origin("https://www.acme.com/", true)
|
.origin(&FromStr::from_str("https://www.acme.com/").unwrap(), true)
|
||||||
.headers(&["Authorization"])
|
.headers(&["Authorization"])
|
||||||
.methods(&options.allowed_methods)
|
.methods(&options.allowed_methods)
|
||||||
.credentials(options.allow_credentials)
|
.credentials(options.allow_credentials)
|
||||||
|
@ -2157,7 +2161,7 @@ mod tests {
|
||||||
|
|
||||||
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
||||||
let expected_response = Response::new()
|
let expected_response = Response::new()
|
||||||
.origin("https://www.acme.com/", false)
|
.origin(&FromStr::from_str("https://www.acme.com/").unwrap(), false)
|
||||||
.credentials(options.allow_credentials)
|
.credentials(options.allow_credentials)
|
||||||
.exposed_headers(&["Content-Type", "X-Custom"]);
|
.exposed_headers(&["Content-Type", "X-Custom"]);
|
||||||
|
|
||||||
|
@ -2180,7 +2184,7 @@ mod tests {
|
||||||
|
|
||||||
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
let response = validate_and_build(&options, request.inner()).expect("to not fail");
|
||||||
let expected_response = Response::new()
|
let expected_response = Response::new()
|
||||||
.origin("https://www.acme.com/", true)
|
.origin(&FromStr::from_str("https://www.acme.com/").unwrap(), true)
|
||||||
.credentials(options.allow_credentials)
|
.credentials(options.allow_credentials)
|
||||||
.exposed_headers(&["Content-Type", "X-Custom"]);
|
.exposed_headers(&["Content-Type", "X-Custom"]);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ fn smoke_test() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -112,7 +112,7 @@ fn cors_options_check() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -135,7 +135,7 @@ fn cors_get_check() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test is to check that non CORS compliant requests to GET should still work. (i.e. curl)
|
/// This test is to check that non CORS compliant requests to GET should still work. (i.e. curl)
|
||||||
|
|
|
@ -119,7 +119,7 @@ fn smoke_test() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -150,7 +150,7 @@ fn cors_options_check() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -174,7 +174,7 @@ fn cors_get_check() {
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Access-Control-Allow-Origin")
|
.get_one("Access-Control-Allow-Origin")
|
||||||
.expect("to exist");
|
.expect("to exist");
|
||||||
assert_eq!("https://www.acme.com/", origin_header);
|
assert_eq!("https://www.acme.com", origin_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test is to check that non CORS compliant requests to GET should still work. (i.e. curl)
|
/// This test is to check that non CORS compliant requests to GET should still work. (i.e. curl)
|
||||||
|
|
Loading…
Reference in New Issue