mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Support for extension methods, getResponseHeader(), and an extra error
This commit is contained in:
parent
1184b500e5
commit
e8de5f2f55
6 changed files with 51 additions and 27 deletions
|
@ -2622,7 +2622,7 @@ use js::jsapi::JSContext;
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
|
|
||||||
#[repr(uint)]
|
#[repr(uint)]
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable, Eq)]
|
||||||
pub enum valuelist {
|
pub enum valuelist {
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub enum Error {
|
||||||
InvalidState,
|
InvalidState,
|
||||||
Syntax,
|
Syntax,
|
||||||
NamespaceError,
|
NamespaceError,
|
||||||
|
InvalidAccess,
|
||||||
Security,
|
Security,
|
||||||
Network
|
Network
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::from_str::FromStr;
|
||||||
use std::hash::{Hash, sip};
|
use std::hash::{Hash, sip};
|
||||||
|
use std::path::BytesContainer;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
#[deriving(Encodable,Clone,TotalEq,Eq)]
|
#[deriving(Encodable,Clone,TotalEq,Eq)]
|
||||||
|
@ -113,4 +115,10 @@ impl Hash for ByteString {
|
||||||
let ByteString(ref vec) = *self;
|
let ByteString(ref vec) = *self;
|
||||||
vec.hash(state);
|
vec.hash(state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ByteString {
|
||||||
|
fn from_str(s: &str) -> Option<ByteString> {
|
||||||
|
Some(ByteString::new(s.container_into_owned_bytes()))
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -46,8 +46,9 @@ impl DOMErrorName {
|
||||||
error::InvalidCharacter => InvalidCharacterError,
|
error::InvalidCharacter => InvalidCharacterError,
|
||||||
error::NotSupported => NotSupportedError,
|
error::NotSupported => NotSupportedError,
|
||||||
error::InvalidState => InvalidStateError,
|
error::InvalidState => InvalidStateError,
|
||||||
error::NamespaceError => NamespaceError,
|
|
||||||
error::Syntax => SyntaxError,
|
error::Syntax => SyntaxError,
|
||||||
|
error::NamespaceError => NamespaceError,
|
||||||
|
error::InvalidAccess => InvalidAccessError,
|
||||||
error::Security => SecurityError,
|
error::Security => SecurityError,
|
||||||
error::Network => NetworkError,
|
error::Network => NetworkError,
|
||||||
error::FailureUnknown => fail!(),
|
error::FailureUnknown => fail!(),
|
||||||
|
|
|
@ -56,7 +56,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
|
||||||
readonly attribute DOMString responseURL;
|
readonly attribute DOMString responseURL;
|
||||||
readonly attribute unsigned short status;
|
readonly attribute unsigned short status;
|
||||||
readonly attribute ByteString statusText;
|
readonly attribute ByteString statusText;
|
||||||
// ByteString? getResponseHeader(ByteString name);
|
ByteString? getResponseHeader(ByteString name);
|
||||||
ByteString getAllResponseHeaders();
|
ByteString getAllResponseHeaders();
|
||||||
// void overrideMimeType(DOMString mime);
|
// void overrideMimeType(DOMString mime);
|
||||||
[SetterThrows]
|
[SetterThrows]
|
||||||
|
|
|
@ -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::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseTypeValues::{_empty, Json, Text};
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived};
|
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, XMLHttpRequestDerived};
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
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::js::{JS, JSRef, Temporary, OptionalSettable, OptionalRootedRootable};
|
||||||
use dom::bindings::str::ByteString;
|
use dom::bindings::str::ByteString;
|
||||||
use dom::bindings::trace::Untraceable;
|
use dom::bindings::trace::Untraceable;
|
||||||
|
@ -30,7 +30,7 @@ use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
use http::headers::content_type::MediaType;
|
use http::headers::content_type::MediaType;
|
||||||
use http::headers::{HeaderEnum, HeaderValueByteIterator};
|
use http::headers::{HeaderEnum, HeaderValueByteIterator};
|
||||||
use http::headers::request::Header;
|
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 http::status::Status;
|
||||||
|
|
||||||
use js::jsapi::{JS_AddObjectRoot, JS_ParseJSON, JS_RemoveObjectRoot, JSContext};
|
use js::jsapi::{JS_AddObjectRoot, JS_ParseJSON, JS_RemoveObjectRoot, JSContext};
|
||||||
|
@ -241,7 +241,7 @@ pub trait XMLHttpRequestMethods<'a> {
|
||||||
fn ResponseURL(&self) -> DOMString;
|
fn ResponseURL(&self) -> DOMString;
|
||||||
fn Status(&self) -> u16;
|
fn Status(&self) -> u16;
|
||||||
fn StatusText(&self) -> ByteString;
|
fn StatusText(&self) -> ByteString;
|
||||||
fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString>;
|
fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString>;
|
||||||
fn GetAllResponseHeaders(&self) -> ByteString;
|
fn GetAllResponseHeaders(&self) -> ByteString;
|
||||||
fn OverrideMimeType(&self, _mime: DOMString);
|
fn OverrideMimeType(&self, _mime: DOMString);
|
||||||
fn ResponseType(&self) -> XMLHttpRequestResponseType;
|
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 {
|
fn Open(&mut self, method: ByteString, url: DOMString) -> ErrorResult {
|
||||||
let maybe_method: Option<Method> = method.as_str().and_then(|s| {
|
let uppercase_method = method.as_str().map(|s| {
|
||||||
FromStr::from_str(s.to_ascii_upper().as_slice()) // rust-http tests against the uppercase versions
|
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
|
// Step 2
|
||||||
let base: Option<Url> = Some(self.global.root().get_url());
|
let base: Option<Url> = Some(self.global.root().get_url());
|
||||||
match maybe_method {
|
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();
|
*self.request_method = maybe_method.unwrap();
|
||||||
|
|
||||||
|
@ -282,8 +299,14 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
Ok(parsed) => parsed,
|
Ok(parsed) => parsed,
|
||||||
Err(_) => return Err(Syntax) // Step 7
|
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 environmet is a document environment
|
||||||
|
if self.timeout != 0 || self.with_credentials || self.response_type != _empty {
|
||||||
|
return Err(InvalidAccess)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// XXXManishearth abort existing requests
|
||||||
// Step 12
|
// Step 12
|
||||||
*self.request_url = parsed_url;
|
*self.request_url = parsed_url;
|
||||||
*self.request_headers = RequestHeaderCollection::new();
|
*self.request_headers = RequestHeaderCollection::new();
|
||||||
|
@ -295,22 +318,9 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
if self.ready_state != Opened {
|
if self.ready_state != Opened {
|
||||||
self.change_ready_state(Opened);
|
self.change_ready_state(Opened);
|
||||||
}
|
}
|
||||||
//XXXManishearth fire a progressevent
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
// XXXManishearth Handle other standard methods
|
_ => Err(Syntax), // Step 3
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn Open_(&mut self, method: ByteString, url: DOMString, async: bool,
|
fn Open_(&mut self, method: ByteString, url: DOMString, async: bool,
|
||||||
|
@ -491,8 +501,12 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
fn StatusText(&self) -> ByteString {
|
fn StatusText(&self) -> ByteString {
|
||||||
self.status_text.clone()
|
self.status_text.clone()
|
||||||
}
|
}
|
||||||
fn GetResponseHeader(&self, _name: ByteString) -> Option<ByteString> {
|
fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString> {
|
||||||
None
|
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 {
|
fn GetAllResponseHeaders(&self) -> ByteString {
|
||||||
let mut writer = MemWriter::new();
|
let mut writer = MemWriter::new();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue