diff options
author | bors-servo <release+servo@mozilla.com> | 2014-06-08 12:22:31 -0400 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-06-08 12:22:31 -0400 |
commit | 1f41eda3215cbb97499855ffb7a5170b488ba00a (patch) | |
tree | f16656fede30585d220fb7e156ab997079318c63 /src/components/script/dom/xmlhttprequest.rs | |
parent | 743dcee0f59d63bfbb820df2412c8e2267b38f66 (diff) | |
parent | 86594a752c1f857df62b058b5d0e4a39fa05e6f3 (diff) | |
download | servo-1f41eda3215cbb97499855ffb7a5170b488ba00a.tar.gz servo-1f41eda3215cbb97499855ffb7a5170b488ba00a.zip |
auto merge of #2613 : Manishearth/servo/xhr-wpt-methods, r=Ms2ger
For [XMLHttpRequest/open-method-case-sensitive.htm](https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/open-method-case-sensitive.htm), [XMLHttpRequest/XMLHttpRequest/open-method-insecure.htm](https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/open-method-insecure.htm), [XMLHttpRequest/XMLHttpRequest/open-method-responsetype-set-sync.htm ](https://github.com/w3c/web-platform-tests/blob/master/XMLHttpRequest/open-method-responsetype-set-sync.htm) in particular. `getResponseHeader()` is used by a lot of other tests (the harness echoes most of the metadata in the response headers, which is tested on this side)
The sync changes fixes half of the timeouts to give meaningful results.
Blocks #2525
Diffstat (limited to 'src/components/script/dom/xmlhttprequest.rs')
-rw-r--r-- | src/components/script/dom/xmlhttprequest.rs | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/src/components/script/dom/xmlhttprequest.rs b/src/components/script/dom/xmlhttprequest.rs index 50ad87aa1c3..cc99bb4ea88 100644 --- a/src/components/script/dom/xmlhttprequest.rs +++ b/src/components/script/dom/xmlhttprequest.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestRespo use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseTypeValues::{_empty, Json, Text}; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived}; use dom::bindings::conversions::ToJSValConvertible; -use dom::bindings::error::{ErrorResult, Fallible, InvalidState, Network, Syntax, Security}; +use dom::bindings::error::{ErrorResult, Fallible, InvalidState, InvalidAccess, Network, Syntax, Security}; use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, OptionalRootedRootable}; use dom::bindings::str::ByteString; use dom::bindings::trace::Untraceable; @@ -30,7 +30,7 @@ use RequestHeaderCollection = http::headers::request::HeaderCollection; use http::headers::content_type::MediaType; use http::headers::{HeaderEnum, HeaderValueByteIterator}; use http::headers::request::Header; -use http::method::{Method, Get, Head, Post, Connect, Trace}; +use http::method::{Method, Get, Head, Connect, Trace, ExtensionMethod}; use http::status::Status; use js::jsapi::{JS_AddObjectRoot, JS_ParseJSON, JS_RemoveObjectRoot, JSContext}; @@ -95,7 +95,7 @@ enum SyncOrAsync<'a, 'b> { impl<'a,'b> SyncOrAsync<'a,'b> { fn is_async(&self) -> bool { match *self { - Sync(_) => true, + Async(_,_) => true, _ => false } } @@ -241,7 +241,7 @@ pub trait XMLHttpRequestMethods<'a> { fn ResponseURL(&self) -> DOMString; fn Status(&self) -> u16; fn StatusText(&self) -> ByteString; - fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString>; + fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString>; fn GetAllResponseHeaders(&self) -> ByteString; fn OverrideMimeType(&self, _mime: DOMString); fn ResponseType(&self) -> XMLHttpRequestResponseType; @@ -267,13 +267,30 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> { } fn Open(&mut self, method: ByteString, url: DOMString) -> ErrorResult { - let maybe_method: Option<Method> = method.as_str().and_then(|s| { - FromStr::from_str(s.to_ascii_upper().as_slice()) // rust-http tests against the uppercase versions + let uppercase_method = method.as_str().map(|s| { + let upper = s.to_ascii_upper(); + match upper.as_slice() { + "DELETE" | "GET" | "HEAD" | "OPTIONS" | + "POST" | "PUT" | "CONNECT" | "TRACE" | + "TRACK" => upper, + _ => s.to_string() + } + }); + let maybe_method: Option<Method> = uppercase_method.and_then(|s| { + // Note: rust-http tests against the uppercase versions + // Since we want to pass methods not belonging to the short list above + // without changing capitalization, this will actually sidestep rust-http's type system + // since methods like "patch" or "PaTcH" will be considered extension methods + // despite the there being a rust-http method variant for them + Method::from_str_or_new(s.as_slice()) }); // Step 2 let base: Option<Url> = Some(self.global.root().get_url()); match maybe_method { - Some(Get) | Some(Post) | Some(Head) => { + // Step 4 + Some(Connect) | Some(Trace) => Err(Security), + Some(ExtensionMethod(ref t)) if t.as_slice() == "TRACK" => Err(Security), + Some(_) if method.is_token() => { *self.request_method = maybe_method.unwrap(); @@ -282,8 +299,14 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> { Ok(parsed) => parsed, Err(_) => return Err(Syntax) // Step 7 }; - // XXXManishearth Do some handling of username/passwords, and abort existing requests - + // XXXManishearth Do some handling of username/passwords + if self.sync { + // FIXME: This should only happen if the global environment is a document environment + if self.timeout != 0 || self.with_credentials || self.response_type != _empty { + return Err(InvalidAccess) + } + } + // XXXManishearth abort existing requests // Step 12 *self.request_url = parsed_url; *self.request_headers = RequestHeaderCollection::new(); @@ -295,22 +318,11 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> { if self.ready_state != Opened { self.change_ready_state(Opened); } - //XXXManishearth fire a progressevent Ok(()) }, - // XXXManishearth Handle other standard methods - Some(Connect) | Some(Trace) => { - // XXXManishearth Track isn't in rust-http, but it should end up in this match arm. - Err(Security) // Step 4 - }, - None => Err(Syntax), // Step 3 - _ => { - if method.is_token() { - Ok(()) // XXXManishearth handle extension methods - } else { - Err(Syntax) // Step 3 - } - } + // This includes cases where as_str() returns None, and when is_token() returns false, + // both of which indicate invalid extension method names + _ => Err(Syntax), // Step 3 } } fn Open_(&mut self, method: ByteString, url: DOMString, async: bool, @@ -491,8 +503,12 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> { fn StatusText(&self) -> ByteString { self.status_text.clone() } - fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString> { - None + fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString> { + self.response_headers.deref().iter().find(|h| { + name.eq_ignore_case(&FromStr::from_str(h.header_name().as_slice()).unwrap()) + }).map(|h| { + FromStr::from_str(h.header_value().as_slice()).unwrap() + }) } fn GetAllResponseHeaders(&self) -> ByteString { let mut writer = MemWriter::new(); |