Auto merge of #12915 - jeenalee:parse-headers, r=Manishearth

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

<!-- Please describe your changes on the following line: -->

The changes in headers.rs will allow headers with "content-type" name to be classified as cors safelisted request headers, 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.

There is possibly one TODO related to this PR:
- Figure out what `name/'invalid'` is in step 4 of the [Headers Delete method](https://fetch.spec.whatwg.org/#dom-headers-delete), and how to implement that.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because web platform tests for the changes already exist.

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

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 as well.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12915)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-08-22 20:17:16 -05:00 committed by GitHub
commit 1e10f8bbf7
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::str::{ByteString, is_token};
use hyper::header::Headers as HyperHeaders;
use mime::{Mime, TopLevel, SubLevel};
use std::cell::Cell;
use std::result::Result;
use std::str;
#[dom_struct]
pub struct Headers {
@ -72,7 +74,7 @@ impl HeadersMethods for Headers {
return Ok(());
}
// 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(());
}
// Step 6
@ -103,9 +105,12 @@ impl HeadersMethods for Headers {
return Ok(());
}
// Step 4
if self.guard.get() == Guard::RequestNoCors && !is_cors_safelisted_request_header(&valid_name) {
return Ok(());
}
// TODO: Requires clarification from the Fetch spec:
// ... 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
if self.guard.get() == Guard::Response && is_forbidden_response_header(&valid_name) {
return Ok(());
@ -148,7 +153,7 @@ impl HeadersMethods for Headers {
return Ok(());
}
// 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(());
}
// Step 6
@ -220,18 +225,35 @@ impl Headers {
}
}
// TODO
// "Content-Type" once parsed, the value should be
// `application/x-www-form-urlencoded`, `multipart/form-data`,
// or `text/plain`.
// "DPR", "Downlink", "Save-Data", "Viewport-Width", "Width":
// once parsed, the value should not be failure.
fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
let value_string = if let Ok(s) = str::from_utf8(value) {
s
} else {
return false;
};
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
fn is_cors_safelisted_request_header(name: &str) -> bool {
fn is_cors_safelisted_request_header(name: &str, value: &[u8]) -> bool {
match name {
"accept" |
"accept-language" |
"content-language" => true,
"content-type" => is_cors_safelisted_request_content_type(value),
_ => false,
}
}

View file

@ -1,23 +1,5 @@
[request-headers.html]
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]
expected: FAIL