diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index b9caa134712..819c85ef564 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -827,7 +827,7 @@ fn http_network_or_cache_fetch(request: Rc, let mut authorization_value = None; // Substep 4 - if let Some(basic) = auth_from_cache(&context.state.auth_cache, ¤t_url) { + if let Some(basic) = auth_from_cache(&context.state.auth_cache, ¤t_url.origin()) { if !http_request.use_url_credentials || !has_credentials(¤t_url) { authorization_value = Some(basic); } diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index d104521c48b..b608220b442 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -52,7 +52,7 @@ use time; use time::Tm; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use tinyfiledialogs; -use url::{Position, Url}; +use url::{Position, Url, Origin}; use util::prefs::PREFS; use util::thread::spawn_named; use uuid; @@ -688,15 +688,15 @@ fn set_auth_header(headers: &mut Headers, if let Some(auth) = auth_from_url(url) { headers.set(auth); } else { - if let Some(basic) = auth_from_cache(auth_cache, url) { + if let Some(basic) = auth_from_cache(auth_cache, &url.origin()) { headers.set(Authorization(basic)); } } } } -pub fn auth_from_cache(auth_cache: &Arc>, url: &Url) -> Option { - if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(url) { +pub fn auth_from_cache(auth_cache: &Arc>, origin: &Origin) -> Option { + if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(&origin.ascii_serialization()) { let user_name = auth_entry.user_name.clone(); let password = Some(auth_entry.password.clone()); Some(Basic { username: user_name, password: password }) @@ -1017,13 +1017,15 @@ pub fn load(load_data: &LoadData, new_auth_header = None; if let Some(auth_header) = request_headers.get::>() { - if response.status().class() == StatusClass::Success { + if response.status().class() == StatusClass::Success || + response.status().class() == StatusClass::Redirection { let auth_entry = AuthCacheEntry { user_name: auth_header.username.to_owned(), password: auth_header.password.to_owned().unwrap(), }; - http_state.auth_cache.write().unwrap().entries.insert(doc_url.clone(), auth_entry); + let serialized_origin = doc_url.origin().ascii_serialization(); + http_state.auth_cache.write().unwrap().entries.insert(serialized_origin, auth_entry); } } diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index d04e4d9b4c0..60699ca84f9 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -466,7 +466,7 @@ impl AuthCache { #[derive(RustcDecodable, RustcEncodable, Clone)] pub struct AuthCache { pub version: u32, - pub entries: HashMap, + pub entries: HashMap, } pub struct CoreResourceManager { diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index 15bd6b8fd25..5530134a15c 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -1533,7 +1533,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() { password: "test".to_owned(), }; - http_state.auth_cache.write().unwrap().entries.insert(url.clone(), auth_entry); + http_state.auth_cache.write().unwrap().entries.insert(url.origin().clone().ascii_serialization(), auth_entry); let mut load_data = LoadData::new(LoadContext::Browsing, url, &HttpTest); load_data.credentials_flag = true; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 855adc0d2f9..4dd9d658d0a 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -37479,6 +37479,20 @@ "deleted": [], "deleted_reftests": {}, "items": { + "reftest": { + "http/basic-auth-cache-test.html": [ + { + "path": "http/basic-auth-cache-test.html", + "references": [ + [ + "/http/basic-auth-cache-test-ref.html", + "==" + ] + ], + "url": "/http/basic-auth-cache-test.html" + } + ] + }, "testharness": { "dom/lists/DOMTokenList-Iterable.html": [ { @@ -37488,7 +37502,20 @@ ] } }, - "reftest_nodes": {} + "reftest_nodes": { + "http/basic-auth-cache-test.html": [ + { + "path": "http/basic-auth-cache-test.html", + "references": [ + [ + "/http/basic-auth-cache-test-ref.html", + "==" + ] + ], + "url": "/http/basic-auth-cache-test.html" + } + ] + } }, "reftest_nodes": { "2dcontext/building-paths/canvas_complexshapes_arcto_001.htm": [ diff --git a/tests/wpt/web-platform-tests/http/basic-auth-cache-test-ref.html b/tests/wpt/web-platform-tests/http/basic-auth-cache-test-ref.html new file mode 100644 index 00000000000..87e9ad509b3 --- /dev/null +++ b/tests/wpt/web-platform-tests/http/basic-auth-cache-test-ref.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/http/basic-auth-cache-test.html b/tests/wpt/web-platform-tests/http/basic-auth-cache-test.html new file mode 100644 index 00000000000..f7fe2b56690 --- /dev/null +++ b/tests/wpt/web-platform-tests/http/basic-auth-cache-test.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/http/resources/image.png b/tests/wpt/web-platform-tests/http/resources/image.png new file mode 100644 index 00000000000..0daa1b519e5 Binary files /dev/null and b/tests/wpt/web-platform-tests/http/resources/image.png differ diff --git a/tests/wpt/web-platform-tests/http/resources/securedimage.py b/tests/wpt/web-platform-tests/http/resources/securedimage.py new file mode 100644 index 00000000000..6f6f0628369 --- /dev/null +++ b/tests/wpt/web-platform-tests/http/resources/securedimage.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 - + +def main(request, response): + image_url = str.replace(request.url, "securedimage.py", "image.png") + + if "authorization" not in request.headers: + response.status = 401 + response.headers.set("WWW-Authenticate", "Basic") + return response + else: + auth = request.headers.get("Authorization") + if auth != "Basic dGVzdHVzZXI6dGVzdHBhc3M=": + response.set_error(403, "Invalid username or password - " + auth) + return response + + response.status = 301 + response.headers.set("Location", image_url)