diff options
author | Daniel <ddefisher@gmail.com> | 2016-03-19 22:02:52 -0400 |
---|---|---|
committer | Daniel <ddefisher@gmail.com> | 2016-03-24 12:24:08 -0400 |
commit | d49d3b01f23ded64e204c263fcfbe86ca9a8c916 (patch) | |
tree | 4927bdb7916b098b806dcb31aa20b84c86709f9e | |
parent | ddc96dca82f0070c91220c884a76e611bbff0661 (diff) | |
download | servo-d49d3b01f23ded64e204c263fcfbe86ca9a8c916.tar.gz servo-d49d3b01f23ded64e204c263fcfbe86ca9a8c916.zip |
add auth cache to resources + set auth header if url does not have creds
-rw-r--r-- | components/net/http_loader.rs | 44 | ||||
-rw-r--r-- | components/net/resource_thread.rs | 8 | ||||
-rw-r--r-- | tests/unit/net/http_loader.rs | 120 |
3 files changed, 146 insertions, 26 deletions
diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index e0227a0637f..dec9e2fd2db 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -31,10 +31,10 @@ use net_traits::response::HttpsState; use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData, Metadata}; use openssl::ssl::error::{SslError, OpensslError}; use openssl::ssl::{SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_VERIFY_PEER, SslContext, SslMethod}; -use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt}; +use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt, AuthCacheEntry}; use std::borrow::ToOwned; use std::boxed::FnBox; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::error::Error; use std::io::{self, Read, Write}; use std::sync::mpsc::Sender; @@ -80,6 +80,7 @@ pub fn create_http_connector() -> Arc<Pool<Connector>> { pub fn factory(user_agent: String, hsts_list: Arc<RwLock<HSTSList>>, cookie_jar: Arc<RwLock<CookieStorage>>, + auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>, devtools_chan: Option<Sender<DevtoolsControlMsg>>, connector: Arc<Pool<Connector>>) -> Box<FnBox(LoadData, @@ -94,6 +95,7 @@ pub fn factory(user_agent: String, connector, hsts_list, cookie_jar, + auth_cache, devtools_chan, cancel_listener, user_agent) @@ -130,6 +132,7 @@ fn load_for_consumer(load_data: LoadData, connector: Arc<Pool<Connector>>, hsts_list: Arc<RwLock<HSTSList>>, cookie_jar: Arc<RwLock<CookieStorage>>, + auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>, devtools_chan: Option<Sender<DevtoolsControlMsg>>, cancel_listener: CancellationListener, user_agent: String) { @@ -139,9 +142,9 @@ fn load_for_consumer(load_data: LoadData, }; let context = load_data.context.clone(); match load::<WrappedHttpRequest>(load_data, hsts_list, - cookie_jar, devtools_chan, - &factory, user_agent, - &cancel_listener) { + cookie_jar, auth_cache, + devtools_chan, &factory, + user_agent, &cancel_listener) { Err(LoadError::UnsupportedScheme(url)) => { let s = format!("{} request, but we don't support that scheme", &*url.scheme); send_error(url, s, start_chan) @@ -516,6 +519,7 @@ pub fn modify_request_headers(headers: &mut Headers, url: &Url, user_agent: &str, cookie_jar: &Arc<RwLock<CookieStorage>>, + auth_cache: &Arc<RwLock<HashMap<Url, AuthCacheEntry>>>, load_data: &LoadData) { // Ensure that the host header is set from the original url let host = Host { @@ -536,19 +540,38 @@ pub fn modify_request_headers(headers: &mut Headers, set_default_accept(headers); set_default_accept_encoding(headers); + // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch step 11 if load_data.credentials_flag { set_request_cookies(url.clone(), headers, cookie_jar); // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 12 - if !headers.has::<Authorization<Basic>>() { - if let Some(auth) = auth_from_url(url) { - headers.set(auth); + set_auth_header(headers, url, auth_cache); + } +} + +fn set_auth_header(headers: &mut Headers, + url: &Url, + auth_cache: &Arc<RwLock<HashMap<Url, AuthCacheEntry>>>) { + + if !headers.has::<Authorization<Basic>>() { + if let Some(auth) = auth_from_url(url) { + headers.set(auth); + } else { + if let Some(ref auth_entry) = auth_cache.read().unwrap().get(url) { + auth_from_entry(&auth_entry, headers); } } } } +fn auth_from_entry(auth_entry: &AuthCacheEntry, headers: &mut Headers) { + let user_name = auth_entry.user_name.clone(); + let password = Some(auth_entry.password.clone()); + + headers.set(Authorization(Basic { username: user_name, password: password })); +} + fn auth_from_url(doc_url: &Url) -> Option<Authorization<Basic>> { match doc_url.username() { Some(username) if username != "" => { @@ -665,6 +688,7 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>, pub fn load<A>(load_data: LoadData, hsts_list: Arc<RwLock<HSTSList>>, cookie_jar: Arc<RwLock<CookieStorage>>, + auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>, devtools_chan: Option<Sender<DevtoolsControlMsg>>, request_factory: &HttpRequestFactory<R=A>, user_agent: String, @@ -730,7 +754,9 @@ pub fn load<A>(load_data: LoadData, let request_id = uuid::Uuid::new_v4().to_simple_string(); - modify_request_headers(&mut request_headers, &doc_url, &user_agent, &cookie_jar, &load_data); + modify_request_headers(&mut request_headers, &doc_url, + &user_agent, &cookie_jar, + &auth_cache, &load_data); let response = try!(obtain_response(request_factory, &doc_url, &method, &request_headers, &cancel_listener, &load_data.data, &load_data.method, diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 89e63e14f79..10530a40b2d 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -269,9 +269,15 @@ impl Drop for CancellationListener { } } +pub struct AuthCacheEntry { + pub user_name: String, + pub password: String, +} + pub struct ResourceManager { user_agent: String, cookie_storage: Arc<RwLock<CookieStorage>>, + auth_cache: Arc<RwLock<HashMap<Url, AuthCacheEntry>>>, mime_classifier: Arc<MIMEClassifier>, devtools_chan: Option<Sender<DevtoolsControlMsg>>, hsts_list: Arc<RwLock<HSTSList>>, @@ -287,6 +293,7 @@ impl ResourceManager { ResourceManager { user_agent: user_agent, cookie_storage: Arc::new(RwLock::new(CookieStorage::new())), + auth_cache: Arc::new(RwLock::new(HashMap::new())), mime_classifier: Arc::new(MIMEClassifier::new()), devtools_chan: devtools_channel, hsts_list: Arc::new(RwLock::new(hsts_list)), @@ -341,6 +348,7 @@ impl ResourceManager { http_loader::factory(self.user_agent.clone(), self.hsts_list.clone(), self.cookie_storage.clone(), + self.auth_cache.clone(), self.devtools_chan.clone(), self.connector.clone()), "data" => from_factory(data_loader::factory), diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index 3f0aa134862..838edd7af1b 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -9,6 +9,7 @@ use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEve use flate2::Compression; use flate2::write::{GzEncoder, DeflateEncoder}; use hyper::header::{Accept, AcceptEncoding, ContentEncoding, ContentLength, Cookie as CookieHeader}; +use hyper::header::{Authorization, Basic}; use hyper::header::{Encoding, Headers, Host, Location, Quality, QualityItem, qitem, SetCookie}; use hyper::header::{StrictTransportSecurity, UserAgent}; use hyper::http::RawStatus; @@ -20,9 +21,10 @@ use net::cookie::Cookie; use net::cookie_storage::CookieStorage; use net::hsts::{HSTSList, HSTSEntry}; use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpResponse}; -use net::resource_thread::CancellationListener; +use net::resource_thread::{AuthCacheEntry, CancellationListener}; use net_traits::{LoadData, CookieSource, LoadContext, IncludeSubdomains}; use std::borrow::Cow; +use std::collections::HashMap; use std::io::{self, Write, Read, Cursor}; use std::sync::mpsc::Receiver; use std::sync::{Arc, mpsc, RwLock}; @@ -375,6 +377,7 @@ fn test_check_default_headers_loaded_in_every_request() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); load_data.data = None; @@ -395,7 +398,8 @@ fn test_check_default_headers_loaded_in_every_request() { headers.set(UserAgent(DEFAULT_USER_AGENT.to_owned())); // Testing for method.GET - let _ = load::<AssertRequestMustHaveHeaders>(load_data.clone(), hsts_list.clone(), cookie_jar.clone(), None, + let _ = load::<AssertRequestMustHaveHeaders>(load_data.clone(), hsts_list.clone(), + cookie_jar.clone(), auth_cache.clone(), None, &AssertMustHaveHeadersRequestFactory { expected_headers: headers.clone(), body: <[_]>::to_vec(&[]) @@ -406,7 +410,7 @@ fn test_check_default_headers_loaded_in_every_request() { headers.set(ContentLength(0 as u64)); - let _ = load::<AssertRequestMustHaveHeaders>(load_data.clone(), hsts_list, cookie_jar, None, + let _ = load::<AssertRequestMustHaveHeaders>(load_data.clone(), hsts_list, cookie_jar, auth_cache.clone(), None, &AssertMustHaveHeadersRequestFactory { expected_headers: headers, body: <[_]>::to_vec(&[]) @@ -419,6 +423,7 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); load_data.data = None; @@ -428,8 +433,8 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length content_length.set(ContentLength(0)); let _ = load::<AssertRequestMustIncludeHeaders>( - load_data.clone(), hsts_list, cookie_jar, None, - &AssertMustIncludeHeadersRequestFactory { + load_data.clone(), hsts_list, cookie_jar, auth_cache, + None, &AssertMustIncludeHeadersRequestFactory { expected_headers: content_length, body: <[_]>::to_vec(&[]) }, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)); @@ -453,6 +458,7 @@ fn test_request_and_response_data_with_network_messages() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let url = url!("https://mozilla.com"); let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>(); @@ -462,7 +468,7 @@ fn test_request_and_response_data_with_network_messages() { let mut request_headers = Headers::new(); request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None }); load_data.headers = request_headers.clone(); - let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, Some(devtools_chan), &Factory, + let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, Some(devtools_chan), &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)); // notification received from devtools @@ -528,11 +534,12 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let url = url!("https://mozilla.com"); let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>(); let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); - let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, Some(devtools_chan), &Factory, + let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, Some(devtools_chan), &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)); // notification received from devtools @@ -565,8 +572,9 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); - let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, None, &Factory, + let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)); } @@ -593,9 +601,10 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let mut response = load::<MockRequest>( - load_data, hsts_list, cookie_jar, None, + load_data, hsts_list, cookie_jar, auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) @@ -626,11 +635,13 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let mut response = load::<MockRequest>( load_data, hsts_list, cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) @@ -671,9 +682,11 @@ fn test_load_doesnt_send_request_body_on_any_redirect() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<AssertMustHaveBodyRequest>( load_data, hsts_list, cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -701,10 +714,12 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<MockRequest>(load_data, hsts_list.clone(), cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -734,10 +749,12 @@ fn test_load_adds_host_to_sts_list_when_url_is_https_and_sts_headers_are_present let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<MockRequest>(load_data, hsts_list.clone(), cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -765,6 +782,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_ let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); assert_cookie_for_domain(cookie_jar.clone(), "http://mozilla.com", ""); @@ -773,6 +791,7 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_ let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar.clone(), + auth_cache.clone(), None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -790,6 +809,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); { let mut cookie_jar = cookie_jar.write().unwrap(); @@ -805,7 +825,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re let mut cookie = Headers::new(); cookie.set(CookieHeader(vec![CookiePair::new("mozillaIs".to_owned(), "theBest".to_owned())])); - let _ = load::<AssertRequestMustIncludeHeaders>(load_data.clone(), hsts_list, cookie_jar, None, + let _ = load::<AssertRequestMustIncludeHeaders>(load_data.clone(), hsts_list, cookie_jar, auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: cookie, body: <[_]>::to_vec(&*load_data.data.unwrap()) @@ -820,6 +840,7 @@ fn test_load_sends_secure_cookie_if_http_changed_to_https_due_to_entry_in_hsts_s let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); { let mut hsts_list = hsts_list.write().unwrap(); @@ -850,7 +871,7 @@ fn test_load_sends_secure_cookie_if_http_changed_to_https_due_to_entry_in_hsts_s headers.set_raw("Cookie".to_owned(), vec![<[_]>::to_vec("mozillaIs=theBest".as_bytes())]); let _ = load::<AssertRequestMustIncludeHeaders>( - load_data.clone(), hsts_list, cookie_jar, None, + load_data.clone(), hsts_list, cookie_jar, auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: headers, body: <[_]>::to_vec(&*load_data.data.unwrap()) @@ -863,6 +884,7 @@ fn test_load_sends_cookie_if_nonhttp() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); { let mut cookie_jar = cookie_jar.write().unwrap(); @@ -882,7 +904,7 @@ fn test_load_sends_cookie_if_nonhttp() { headers.set_raw("Cookie".to_owned(), vec![<[_]>::to_vec("mozillaIs=theBest".as_bytes())]); let _ = load::<AssertRequestMustIncludeHeaders>( - load_data.clone(), hsts_list, cookie_jar, None, + load_data.clone(), hsts_list, cookie_jar, auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: headers, body: <[_]>::to_vec(&*load_data.data.unwrap()) @@ -908,10 +930,12 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl( let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar.clone(), + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -938,10 +962,12 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let load_data = LoadData::new(LoadContext::Browsing, url!("http://mozilla.com"), None); let _ = load::<MockRequest>(load_data, hsts_list, cookie_jar.clone(), + auth_cache.clone(), None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -958,6 +984,7 @@ fn test_when_cookie_set_marked_httpsonly_secure_isnt_sent_on_http_request() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); { let mut cookie_jar = cookie_jar.write().unwrap(); @@ -976,7 +1003,7 @@ fn test_when_cookie_set_marked_httpsonly_secure_isnt_sent_on_http_request() { assert_cookie_for_domain(cookie_jar.clone(), "https://mozilla.com", "mozillaIs=theBest"); let _ = load::<AssertRequestMustNotIncludeHeaders>( - load_data.clone(), hsts_list, cookie_jar, None, + load_data.clone(), hsts_list, cookie_jar, auth_cache, None, &AssertMustNotIncludeHeadersRequestFactory { headers_not_expected: vec!["Cookie".to_owned()], body: <[_]>::to_vec(&*load_data.data.unwrap()) @@ -996,8 +1023,9 @@ fn test_load_sets_content_length_to_length_of_request_body() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); - let _ = load::<AssertRequestMustIncludeHeaders>(load_data.clone(), hsts_list, cookie_jar, + let _ = load::<AssertRequestMustIncludeHeaders>(load_data.clone(), hsts_list, cookie_jar, auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: content_len_headers, body: <[_]>::to_vec(&*load_data.data.unwrap()) @@ -1019,10 +1047,12 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: accept_headers, @@ -1047,10 +1077,12 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: accept_headers, @@ -1071,10 +1103,12 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: accept_encoding_headers, @@ -1096,10 +1130,12 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); let _ = load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &AssertMustIncludeHeadersRequestFactory { expected_headers: accept_encoding_headers, @@ -1131,8 +1167,9 @@ fn test_load_errors_when_there_a_redirect_loop() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); - match load::<MockRequest>(load_data, hsts_list, cookie_jar, None, &Factory, + match load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) { Err(LoadError::InvalidRedirect(_, msg)) => { assert_eq!(msg, "redirect loop"); @@ -1162,8 +1199,9 @@ fn test_load_errors_when_there_is_too_many_redirects() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); - match load::<MockRequest>(load_data, hsts_list, cookie_jar, None, &Factory, + match load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) { Err(LoadError::MaxRedirects(url)) => { assert_eq!(url.domain().unwrap(), "mozilla.com") @@ -1201,8 +1239,9 @@ fn test_load_follows_a_redirect() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); - match load::<MockRequest>(load_data, hsts_list, cookie_jar, None, &Factory, + match load::<MockRequest>(load_data, hsts_list, cookie_jar, auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) { Err(e) => panic!("expected to follow a redirect {:?}", e), Ok(mut lr) => { @@ -1229,10 +1268,12 @@ fn test_load_errors_when_scheme_is_not_http_or_https() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); match load::<MockRequest>(load_data, hsts_list, cookie_jar, + auth_cache, None, &DontConnectFactory, DEFAULT_USER_AGENT.to_owned(), @@ -1249,10 +1290,12 @@ fn test_load_errors_when_viewing_source_and_inner_url_scheme_is_not_http_or_http let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); match load::<MockRequest>(load_data, hsts_list, cookie_jar, + auth_cache, None, &DontConnectFactory, DEFAULT_USER_AGENT.to_owned(), @@ -1292,10 +1335,12 @@ fn test_load_errors_when_cancelled() { let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None); let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); match load::<MockRequest>(load_data, hsts_list, cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -1341,6 +1386,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); { let mut cookie_jar = cookie_jar.write().unwrap(); @@ -1365,6 +1411,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() { match load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -1410,10 +1457,12 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() { let hsts_list = Arc::new(RwLock::new(HSTSList::new())); let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); match load::<AssertRequestMustIncludeHeaders>(load_data, hsts_list, cookie_jar, + auth_cache, None, &Factory, DEFAULT_USER_AGENT.to_owned(), @@ -1425,3 +1474,40 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() { } } } + +#[test] +fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() { + let url = url!("http://mozilla.com"); + + let hsts_list = Arc::new(RwLock::new(HSTSList::new())); + let cookie_jar = Arc::new(RwLock::new(CookieStorage::new())); + let auth_cache = Arc::new(RwLock::new(HashMap::new())); + + let auth_entry = AuthCacheEntry { + user_name: "username".to_owned(), + password: "test".to_owned(), + }; + + auth_cache.write().unwrap().insert(url.clone(), auth_entry); + + let mut load_data = LoadData::new(LoadContext::Browsing, url, None); + load_data.credentials_flag = true; + + let mut auth_header = Headers::new(); + + auth_header.set( + Authorization( + Basic { + username: "username".to_owned(), + password: Some("test".to_owned()) + } + ) + ); + + let _ = load::<AssertRequestMustIncludeHeaders>( + load_data.clone(), hsts_list, cookie_jar, auth_cache, + None, &AssertMustIncludeHeadersRequestFactory { + expected_headers: auth_header, + body: <[_]>::to_vec(&[]) + }, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)); +} |