From 10e7af50fef1aad7571748fa620a7b9d21c00d44 Mon Sep 17 00:00:00 2001 From: Daniel Robertson Date: Sat, 13 Feb 2016 01:00:23 +0000 Subject: [PATCH 1/2] Implement step 9 of XHR open method Implement step 9 of the Open method for XMLHttpRequest. --- components/script/dom/xmlhttprequest.rs | 29 ++++++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index d81bfe4ab7c..0f0fbecf66f 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -60,6 +60,7 @@ use string_cache::Atom; use time; use timers::{ScheduledCallback, TimerHandle}; use url::Url; +use url::percent_encoding::{utf8_percent_encode, USERNAME_ENCODE_SET, PASSWORD_ENCODE_SET}; use util::str::DOMString; pub type SendParam = BlobOrStringOrURLSearchParams; @@ -293,7 +294,9 @@ impl XMLHttpRequestMethods for XMLHttpRequest { } // https://xhr.spec.whatwg.org/#the-open()-method - fn Open(&self, method: ByteString, url: USVString) -> ErrorResult { + fn Open_(&self, method: ByteString, url: USVString, async: bool, + username: Option, password: Option) -> ErrorResult { + self.sync.set(!async); //FIXME(seanmonstar): use a Trie instead? let maybe_method = method.as_str().and_then(|s| { // Note: hyper tests against the uppercase versions @@ -324,10 +327,11 @@ impl XMLHttpRequestMethods for XMLHttpRequest { // Step 6 let base = self.global().r().get_url(); - let parsed_url = match base.join(&url.0) { + let mut parsed_url = match base.join(&url.0) { Ok(parsed) => parsed, Err(_) => return Err(Error::Syntax) // Step 7 }; + // XXXManishearth Do some handling of username/passwords if self.sync.get() { // FIXME: This should only happen if the global environment is a document environment @@ -336,6 +340,21 @@ impl XMLHttpRequestMethods for XMLHttpRequest { return Err(Error::InvalidAccess) } } + + if parsed_url.host().is_some() { + if let Some(scheme_data) = parsed_url.relative_scheme_data_mut() { + if let Some(user_str) = username { + scheme_data.username = utf8_percent_encode(&user_str.0, USERNAME_ENCODE_SET); + + // ensure that the password is mutated when a username is provided + scheme_data.password = match password { + Some(pass_str) => Some(utf8_percent_encode(&pass_str.0, PASSWORD_ENCODE_SET)), + None => None + } + } + } + } + // abort existing requests self.terminate_ongoing_fetch(); @@ -359,10 +378,8 @@ impl XMLHttpRequestMethods for XMLHttpRequest { } // https://xhr.spec.whatwg.org/#the-open()-method - fn Open_(&self, method: ByteString, url: USVString, async: bool, - _username: Option, _password: Option) -> ErrorResult { - self.sync.set(!async); - self.Open(method, url) + fn Open(&self, method: ByteString, url: USVString) -> ErrorResult { + self.Open_(method, url, true, None, None) } // https://xhr.spec.whatwg.org/#the-setrequestheader()-method From 4d15b02dde8de3204bed1b9fb9e118779fea2b0f Mon Sep 17 00:00:00 2001 From: Daniel Robertson Date: Mon, 15 Feb 2016 05:00:57 +0000 Subject: [PATCH 2/2] Handle credentials in modify_request_headers Handle credentials and set the apropriate header in `modify_request_headers`. --- components/net/http_loader.rs | 20 +++++++++++++++++++ ...tication-competing-names-passwords.htm.ini | 20 ------------------- 2 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 tests/wpt/metadata/XMLHttpRequest/send-authentication-competing-names-passwords.htm.ini diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index e21ade1b2ad..cad5cef6999 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -14,6 +14,7 @@ use hsts::{HSTSEntry, HSTSList, secure_url}; use hyper::Error as HttpError; use hyper::client::{Pool, Request, Response}; use hyper::header::{Accept, AcceptEncoding, ContentLength, ContentType, Host}; +use hyper::header::{Authorization, Basic}; use hyper::header::{ContentEncoding, Encoding, Header, Headers, Quality, QualityItem}; use hyper::header::{Location, SetCookie, StrictTransportSecurity, UserAgent, qitem}; use hyper::http::RawStatus; @@ -529,6 +530,25 @@ pub fn modify_request_headers(headers: &mut Headers, // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch step 11 if load_data.credentials_flag { set_request_cookies(doc_url.clone(), headers, cookie_jar); + + // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 12 + if !headers.has::>() { + if let Some(auth) = auth_from_url(doc_url) { + headers.set(auth); + } + } + } +} + +fn auth_from_url(doc_url: &Url) -> Option> { + match doc_url.username() { + Some(username) if username != "" => { + Some(Authorization(Basic { + username: username.to_owned(), + password: Some(doc_url.password().unwrap_or("").to_owned()) + })) + }, + _ => None } } diff --git a/tests/wpt/metadata/XMLHttpRequest/send-authentication-competing-names-passwords.htm.ini b/tests/wpt/metadata/XMLHttpRequest/send-authentication-competing-names-passwords.htm.ini deleted file mode 100644 index b74829cdec5..00000000000 --- a/tests/wpt/metadata/XMLHttpRequest/send-authentication-competing-names-passwords.htm.ini +++ /dev/null @@ -1,20 +0,0 @@ -[send-authentication-competing-names-passwords.htm] - type: testharness - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options user/pass in open() call] - expected: FAIL - - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options another user/pass in open() call - must override cached credentials from previous test] - expected: FAIL - - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options user/pass both in URL userinfo AND open() call - expexted that open() wins] - expected: FAIL - - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options user/pass *only* in URL userinfo] - expected: FAIL - - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options user name in URL userinfo, password in open() call: user name wins and password is thrown away] - expected: FAIL - - [XMLHttpRequest: send() - "Basic" authenticated requests with competing user name/password options user name and password in URL userinfo, only user name in open() call: user name in open() wins] - expected: FAIL -