Include "content-type" in cors safelisted request headers.

This commit allows headers with "content-type" name to be classified as valid header name, depending on its value according to [the Fetch spec](https://fetch.spec.whatwg.org/#cors-safelisted-request-header). As a result of this change, more request web platform tests pass, whose expected test results are updated with this commit.
This commit is contained in:
Jeena Lee 2016-08-17 15:03:46 -07:00
parent cb01d37338
commit cc7b1c508a
2 changed files with 34 additions and 30 deletions

View file

@ -12,8 +12,10 @@ use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, is_token}; use dom::bindings::str::{ByteString, is_token};
use hyper::header::Headers as HyperHeaders; use hyper::header::Headers as HyperHeaders;
use mime::{Mime, TopLevel, SubLevel};
use std::cell::Cell; use std::cell::Cell;
use std::result::Result; use std::result::Result;
use std::str;
#[dom_struct] #[dom_struct]
pub struct Headers { pub struct Headers {
@ -72,7 +74,7 @@ impl HeadersMethods for Headers {
return Ok(()); return Ok(());
} }
// Step 5 // Step 5
if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) { if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name, &valid_value) {
return Ok(()); return Ok(());
} }
// Step 6 // Step 6
@ -103,9 +105,12 @@ impl HeadersMethods for Headers {
return Ok(()); return Ok(());
} }
// Step 4 // Step 4
if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) { // TODO: Requires clarification from the Fetch spec:
return Ok(()); // ... https://github.com/whatwg/fetch/issues/372
} if self.guard.get() == Guard::RequestNoCors &&
!is_cors_safelisted_request_header(&valid_name, &b"invalid".to_vec()) {
return Ok(());
}
// Step 5 // Step 5
if self.guard.get() == Guard::Response && is_forbidden_response_header(&valid_name) { if self.guard.get() == Guard::Response && is_forbidden_response_header(&valid_name) {
return Ok(()); return Ok(());
@ -148,7 +153,7 @@ impl HeadersMethods for Headers {
return Ok(()); return Ok(());
} }
// Step 5 // Step 5
if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) { if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name, &valid_value) {
return Ok(()); return Ok(());
} }
// Step 6 // Step 6
@ -220,18 +225,35 @@ impl Headers {
} }
} }
// TODO fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
// "Content-Type" once parsed, the value should be let value_string = if let Ok(s) = str::from_utf8(value) {
// `application/x-www-form-urlencoded`, `multipart/form-data`, s
// or `text/plain`. } else {
// "DPR", "Downlink", "Save-Data", "Viewport-Width", "Width": return false;
// once parsed, the value should not be failure. };
let value_mime_result: Result<Mime, _> = value_string.parse();
match value_mime_result {
Err(_) => false,
Ok(value_mime) => {
match value_mime {
Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _) |
Mime(TopLevel::Multipart, SubLevel::FormData, _) |
Mime(TopLevel::Text, SubLevel::Plain, _) => true,
_ => false,
}
}
}
}
// TODO: "DPR", "Downlink", "Save-Data", "Viewport-Width", "Width":
// ... once parsed, the value should not be failure.
// https://fetch.spec.whatwg.org/#cors-safelisted-request-header // https://fetch.spec.whatwg.org/#cors-safelisted-request-header
fn is_cors_safelisted_request_header(name: &str) -> bool { fn is_cors_safelisted_request_header(name: &str, value: &[u8]) -> bool {
match name { match name {
"accept" | "accept" |
"accept-language" | "accept-language" |
"content-language" => true, "content-language" => true,
"content-type" => is_cors_safelisted_request_content_type(value),
_ => false, _ => false,
} }
} }

View file

@ -1,23 +1,5 @@
[request-headers.html] [request-headers.html]
type: testharness type: testharness
[Adding valid no-cors request header "content-type: application/x-www-form-urlencoded"]
expected: FAIL
[Adding valid no-cors request header "content-type: application/x-www-form-urlencoded;charset=UTF-8"]
expected: FAIL
[Adding valid no-cors request header "content-type: multipart/form-data"]
expected: FAIL
[Adding valid no-cors request header "content-type: multipart/form-data;charset=UTF-8"]
expected: FAIL
[Adding valid no-cors request header "content-TYPE: text/plain"]
expected: FAIL
[Adding valid no-cors request header "CONTENT-type: text/plain;charset=UTF-8"]
expected: FAIL
[Request should get its content-type from the body if none is provided] [Request should get its content-type from the body if none is provided]
expected: FAIL expected: FAIL