aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py2
-rw-r--r--src/components/script/dom/bindings/error.rs1
-rw-r--r--src/components/script/dom/bindings/str.rs12
-rw-r--r--src/components/script/dom/domexception.rs3
-rw-r--r--src/components/script/dom/webidls/XMLHttpRequest.webidl2
-rw-r--r--src/components/script/dom/xmlhttprequest.rs66
6 files changed, 58 insertions, 28 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 7ddf982166b..b31c1d128a4 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2627,7 +2627,7 @@ use js::jsapi::JSContext;
use js::jsval::JSVal;
#[repr(uint)]
-#[deriving(Encodable)]
+#[deriving(Encodable, Eq)]
pub enum valuelist {
%s
}
diff --git a/src/components/script/dom/bindings/error.rs b/src/components/script/dom/bindings/error.rs
index db3337b6de2..974ad91d8a6 100644
--- a/src/components/script/dom/bindings/error.rs
+++ b/src/components/script/dom/bindings/error.rs
@@ -26,6 +26,7 @@ pub enum Error {
InvalidState,
Syntax,
NamespaceError,
+ InvalidAccess,
Security,
Network
}
diff --git a/src/components/script/dom/bindings/str.rs b/src/components/script/dom/bindings/str.rs
index e7d84d21c07..ae6c721abea 100644
--- a/src/components/script/dom/bindings/str.rs
+++ b/src/components/script/dom/bindings/str.rs
@@ -2,7 +2,9 @@
* 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/. */
+use std::from_str::FromStr;
use std::hash::{Hash, sip};
+use std::path::BytesContainer;
use std::str;
#[deriving(Encodable,Clone,TotalEq,Eq)]
@@ -45,6 +47,9 @@ impl ByteString {
pub fn is_token(&self) -> bool {
let ByteString(ref vec) = *self;
+ if vec.len() == 0 {
+ return false; // A token must be at least a single character
+ }
vec.iter().all(|&x| {
// http://tools.ietf.org/html/rfc2616#section-2.2
match x {
@@ -53,6 +58,7 @@ impl ByteString {
44 | 59 | 58 | 92 | 34 |
47 | 91 | 93 | 63 | 61 |
123 | 125 | 32 => false, // separators
+ x if x > 127 => false, // non-CHARs
_ => true
}
})
@@ -113,4 +119,10 @@ impl Hash for ByteString {
let ByteString(ref vec) = *self;
vec.hash(state);
}
+}
+
+impl FromStr for ByteString {
+ fn from_str(s: &str) -> Option<ByteString> {
+ Some(ByteString::new(s.container_into_owned_bytes()))
+ }
} \ No newline at end of file
diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs
index bd59020dbbd..262ae5c3fa8 100644
--- a/src/components/script/dom/domexception.rs
+++ b/src/components/script/dom/domexception.rs
@@ -46,8 +46,9 @@ impl DOMErrorName {
error::InvalidCharacter => InvalidCharacterError,
error::NotSupported => NotSupportedError,
error::InvalidState => InvalidStateError,
- error::NamespaceError => NamespaceError,
error::Syntax => SyntaxError,
+ error::NamespaceError => NamespaceError,
+ error::InvalidAccess => InvalidAccessError,
error::Security => SecurityError,
error::Network => NetworkError,
error::FailureUnknown => fail!(),
diff --git a/src/components/script/dom/webidls/XMLHttpRequest.webidl b/src/components/script/dom/webidls/XMLHttpRequest.webidl
index ab06165a098..e0aa3710c57 100644
--- a/src/components/script/dom/webidls/XMLHttpRequest.webidl
+++ b/src/components/script/dom/webidls/XMLHttpRequest.webidl
@@ -56,7 +56,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
readonly attribute DOMString responseURL;
readonly attribute unsigned short status;
readonly attribute ByteString statusText;
- // ByteString? getResponseHeader(ByteString name);
+ ByteString? getResponseHeader(ByteString name);
ByteString getAllResponseHeaders();
// void overrideMimeType(DOMString mime);
[SetterThrows]
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();