mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Auto merge of #10328 - DDEFISHER:master, r=jdm
401 authorization UI then restart request/save successful auth creds Step 7 of the NCSU student project Implement HTTP authorization UI > make an authorization UI appear when a 401 HTTP response is received (StatusCode::Unauthorized) - in load in http_loader.rs, right before trying to process an HTTP redirection, use the new tinyfiledialogs library to make two prompts appear (username and password), then restart the request with the new authorization value present applied. If an authorization value was present and the response is successful, add the credentials to the authorization cache. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10328) <!-- Reviewable:end -->
This commit is contained in:
commit
7bd2381518
7 changed files with 282 additions and 61 deletions
|
@ -32,6 +32,9 @@ git = "https://github.com/servo/ipc-channel"
|
|||
[dependencies.webrender_traits]
|
||||
git = "https://github.com/servo/webrender_traits"
|
||||
|
||||
[dependencies.tinyfiledialogs]
|
||||
git = "https://github.com/jdm/tinyfiledialogs"
|
||||
|
||||
[dependencies]
|
||||
cookie = "0.2"
|
||||
flate2 = "0.2.0"
|
||||
|
|
|
@ -41,6 +41,7 @@ use std::sync::mpsc::Sender;
|
|||
use std::sync::{Arc, RwLock};
|
||||
use time;
|
||||
use time::Tm;
|
||||
use tinyfiledialogs;
|
||||
use url::Url;
|
||||
use util::resource_files::resources_dir_path;
|
||||
use util::thread::spawn_named;
|
||||
|
@ -150,8 +151,10 @@ fn load_for_consumer(load_data: LoadData,
|
|||
let factory = NetworkHttpRequestFactory {
|
||||
connector: connector,
|
||||
};
|
||||
|
||||
let ui_provider = TFDProvider;
|
||||
let context = load_data.context.clone();
|
||||
match load::<WrappedHttpRequest>(load_data, &http_state,
|
||||
match load::<WrappedHttpRequest, TFDProvider>(load_data, &ui_provider, &http_state,
|
||||
devtools_chan, &factory,
|
||||
user_agent, &cancel_listener) {
|
||||
Err(LoadError::UnsupportedScheme(url)) => {
|
||||
|
@ -694,13 +697,27 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
pub fn load<A>(load_data: LoadData,
|
||||
pub trait UIProvider {
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>);
|
||||
}
|
||||
|
||||
impl UIProvider for TFDProvider {
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
||||
(tinyfiledialogs::input_box("Enter username", "Username:", ""),
|
||||
tinyfiledialogs::input_box("Enter password", "Password:", ""))
|
||||
}
|
||||
}
|
||||
|
||||
struct TFDProvider;
|
||||
|
||||
pub fn load<A, B>(load_data: LoadData,
|
||||
ui_provider: &B,
|
||||
http_state: &HttpState,
|
||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||
request_factory: &HttpRequestFactory<R=A>,
|
||||
user_agent: String,
|
||||
cancel_listener: &CancellationListener)
|
||||
-> Result<StreamedResponse<A::R>, LoadError> where A: HttpRequest + 'static {
|
||||
-> Result<StreamedResponse<A::R>, LoadError> where A: HttpRequest + 'static, B: UIProvider {
|
||||
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
||||
// location for configuration. If you're reading this and such a
|
||||
// repository DOES exist, please update this constant to use it.
|
||||
|
@ -711,6 +728,8 @@ pub fn load<A>(load_data: LoadData,
|
|||
let mut redirected_to = HashSet::new();
|
||||
let mut method = load_data.method.clone();
|
||||
|
||||
let mut new_auth_header: Option<Authorization<Basic>> = None;
|
||||
|
||||
if cancel_listener.is_cancelled() {
|
||||
return Err(LoadError::Cancelled(doc_url, "load cancelled".to_owned()));
|
||||
}
|
||||
|
@ -765,12 +784,43 @@ pub fn load<A>(load_data: LoadData,
|
|||
&user_agent, &http_state.cookie_jar,
|
||||
&http_state.auth_cache, &load_data);
|
||||
|
||||
//if there is a new auth header then set the request headers with it
|
||||
if let Some(ref auth_header) = new_auth_header {
|
||||
request_headers.set(auth_header.clone());
|
||||
}
|
||||
|
||||
let response = try!(obtain_response(request_factory, &doc_url, &method, &request_headers,
|
||||
&cancel_listener, &load_data.data, &load_data.method,
|
||||
&load_data.pipeline_id, iters, &devtools_chan, &request_id));
|
||||
|
||||
process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data);
|
||||
|
||||
//if response status is unauthorized then prompt user for username and password
|
||||
if response.status() == StatusCode::Unauthorized {
|
||||
let (username_option, password_option) = ui_provider.input_username_and_password();
|
||||
|
||||
match username_option {
|
||||
Some(name) => {
|
||||
new_auth_header = Some(Authorization(Basic { username: name, password: password_option }));
|
||||
continue;
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
|
||||
new_auth_header = None;
|
||||
|
||||
if let Some(auth_header) = request_headers.get::<Authorization<Basic>>() {
|
||||
if response.status().class() == StatusClass::Success {
|
||||
let auth_entry = AuthCacheEntry {
|
||||
user_name: auth_header.username.to_owned(),
|
||||
password: auth_header.password.to_owned().unwrap(),
|
||||
};
|
||||
|
||||
http_state.auth_cache.write().unwrap().insert(doc_url.clone(), auth_entry);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Loop if there's a redirect
|
||||
if response.status().class() == StatusClass::Redirection {
|
||||
if let Some(&Location(ref new_url)) = response.headers().get::<Location>() {
|
||||
|
|
|
@ -29,6 +29,7 @@ extern crate openssl;
|
|||
extern crate rustc_serialize;
|
||||
extern crate threadpool;
|
||||
extern crate time;
|
||||
extern crate tinyfiledialogs;
|
||||
extern crate unicase;
|
||||
extern crate url;
|
||||
extern crate util;
|
||||
|
|
9
components/servo/Cargo.lock
generated
9
components/servo/Cargo.lock
generated
|
@ -1286,6 +1286,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
|
@ -2090,6 +2091,14 @@ dependencies = [
|
|||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyfiledialogs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/jdm/tinyfiledialogs#2d2285985db1168da4d516000f24842aba46fd94"
|
||||
dependencies = [
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
version = "0.0.1"
|
||||
|
|
9
ports/cef/Cargo.lock
generated
9
ports/cef/Cargo.lock
generated
|
@ -1199,6 +1199,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
|
@ -1976,6 +1977,14 @@ dependencies = [
|
|||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyfiledialogs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/jdm/tinyfiledialogs#2d2285985db1168da4d516000f24842aba46fd94"
|
||||
dependencies = [
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
version = "0.0.1"
|
||||
|
|
9
ports/gonk/Cargo.lock
generated
9
ports/gonk/Cargo.lock
generated
|
@ -1181,6 +1181,7 @@ dependencies = [
|
|||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
|
@ -1956,6 +1957,14 @@ dependencies = [
|
|||
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyfiledialogs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/jdm/tinyfiledialogs#2d2285985db1168da4d516000f24842aba46fd94"
|
||||
dependencies = [
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "traitobject"
|
||||
version = "0.0.1"
|
||||
|
|
|
@ -20,7 +20,7 @@ use msg::constellation_msg::PipelineId;
|
|||
use net::cookie::Cookie;
|
||||
use net::cookie_storage::CookieStorage;
|
||||
use net::hsts::HSTSEntry;
|
||||
use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpResponse, HttpState};
|
||||
use net::http_loader::{load, LoadError, HttpRequestFactory, HttpRequest, HttpResponse, UIProvider, HttpState};
|
||||
use net::resource_thread::{AuthCacheEntry, CancellationListener};
|
||||
use net_traits::{LoadData, CookieSource, LoadContext, IncludeSubdomains};
|
||||
use std::borrow::Cow;
|
||||
|
@ -96,6 +96,33 @@ fn redirect_to(host: String) -> MockResponse {
|
|||
)
|
||||
}
|
||||
|
||||
struct TestProvider {
|
||||
username: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
impl TestProvider {
|
||||
fn new() -> TestProvider {
|
||||
TestProvider { username: "default".to_owned(), password: "default".to_owned() }
|
||||
}
|
||||
}
|
||||
impl UIProvider for TestProvider {
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
||||
(Some(self.username.to_owned()),
|
||||
Some(self.password.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn basic_auth(headers: Headers) -> MockResponse {
|
||||
|
||||
MockResponse::new(
|
||||
headers,
|
||||
StatusCode::Unauthorized,
|
||||
RawStatus(401, Cow::Borrowed("Unauthorized")),
|
||||
b"".to_vec()
|
||||
)
|
||||
}
|
||||
|
||||
fn redirect_with_headers(host: String, mut headers: Headers) -> MockResponse {
|
||||
headers.set(Location(host.to_string()));
|
||||
|
||||
|
@ -132,7 +159,7 @@ fn response_for_request_type(t: ResponseType) -> Result<MockResponse, LoadError>
|
|||
},
|
||||
ResponseType::RedirectWithHeaders(location, headers) => {
|
||||
Ok(redirect_with_headers(location, headers))
|
||||
}
|
||||
},
|
||||
ResponseType::Text(b) => {
|
||||
Ok(respond_with(b))
|
||||
},
|
||||
|
@ -171,7 +198,41 @@ impl HttpRequest for AssertRequestMustHaveHeaders {
|
|||
|
||||
fn send(self, _: &Option<Vec<u8>>) -> Result<MockResponse, LoadError> {
|
||||
assert_eq!(self.request_headers, self.expected_headers);
|
||||
response_for_request_type(self.t)
|
||||
response_for_request_type(self.t)
|
||||
}
|
||||
}
|
||||
|
||||
struct AssertAuthHeaderRequest {
|
||||
expected_headers: Headers,
|
||||
request_headers: Headers,
|
||||
t: ResponseType
|
||||
}
|
||||
|
||||
impl AssertAuthHeaderRequest {
|
||||
fn new(t: ResponseType, expected_headers: Headers) -> Self {
|
||||
AssertAuthHeaderRequest { expected_headers: expected_headers, request_headers: Headers::new(), t: t }
|
||||
}
|
||||
}
|
||||
|
||||
impl HttpRequest for AssertAuthHeaderRequest {
|
||||
type R = MockResponse;
|
||||
|
||||
fn headers_mut(&mut self) -> &mut Headers { &mut self.request_headers }
|
||||
|
||||
fn send(self, _: &Option<Vec<u8>>) -> Result<MockResponse, LoadError> {
|
||||
|
||||
if self.request_headers.has::<Authorization<Basic>>() {
|
||||
for header in self.expected_headers.iter() {
|
||||
assert!(self.request_headers.get_raw(header.name()).is_some());
|
||||
assert_eq!(
|
||||
self.request_headers.get_raw(header.name()).unwrap(),
|
||||
self.expected_headers.get_raw(header.name()).unwrap()
|
||||
)
|
||||
}
|
||||
response_for_request_type(self.t)
|
||||
} else {
|
||||
Ok(basic_auth(self.request_headers))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,6 +297,23 @@ impl HttpRequestFactory for AssertMustHaveHeadersRequestFactory {
|
|||
}
|
||||
}
|
||||
|
||||
struct AssertAuthHeaderRequestFactory {
|
||||
expected_headers: Headers,
|
||||
body: Vec<u8>
|
||||
}
|
||||
|
||||
impl HttpRequestFactory for AssertAuthHeaderRequestFactory {
|
||||
type R = AssertAuthHeaderRequest;
|
||||
|
||||
fn create(&self, _: Url, _: Method) -> Result<AssertAuthHeaderRequest, LoadError> {
|
||||
Ok(
|
||||
AssertAuthHeaderRequest::new(
|
||||
ResponseType::Text(self.body.clone()),
|
||||
self.expected_headers.clone()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: Headers,
|
||||
|
@ -375,6 +453,7 @@ fn test_check_default_headers_loaded_in_every_request() {
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
load_data.data = None;
|
||||
|
@ -395,7 +474,7 @@ 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(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustHaveHeaders, TestProvider>(load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustHaveHeadersRequestFactory {
|
||||
expected_headers: headers.clone(),
|
||||
body: <[_]>::to_vec(&[])
|
||||
|
@ -406,7 +485,7 @@ fn test_check_default_headers_loaded_in_every_request() {
|
|||
|
||||
headers.set(ContentLength(0 as u64));
|
||||
|
||||
let _ = load::<AssertRequestMustHaveHeaders>(load_data.clone(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustHaveHeaders, TestProvider>(load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustHaveHeadersRequestFactory {
|
||||
expected_headers: headers,
|
||||
body: <[_]>::to_vec(&[])
|
||||
|
@ -418,6 +497,7 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
load_data.data = None;
|
||||
|
@ -426,8 +506,8 @@ fn test_load_when_request_is_not_get_or_head_and_there_is_no_body_content_length
|
|||
let mut content_length = Headers::new();
|
||||
content_length.set(ContentLength(0));
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(
|
||||
load_data.clone(), &http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state,
|
||||
None, &AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: content_length,
|
||||
body: <[_]>::to_vec(&[])
|
||||
|
@ -451,6 +531,7 @@ fn test_request_and_response_data_with_network_messages() {
|
|||
}
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let url = Url::parse("https://mozilla.com").unwrap();
|
||||
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
||||
|
@ -460,7 +541,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, &http_state, Some(devtools_chan), &Factory,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, Some(devtools_chan), &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||
|
||||
// notification received from devtools
|
||||
|
@ -525,11 +606,12 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
|
|||
}
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let url = Url::parse("https://mozilla.com").unwrap();
|
||||
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
let _ = load::<MockRequest>(load_data, &http_state, Some(devtools_chan), &Factory,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, Some(devtools_chan), &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||
|
||||
// notification received from devtools
|
||||
|
@ -561,8 +643,9 @@ fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() {
|
|||
load_data.method = Method::Post;
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<MockRequest>(load_data, &http_state, None, &Factory,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, None, &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||
}
|
||||
|
||||
|
@ -588,9 +671,10 @@ fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_co
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let mut response = load::<MockRequest>(
|
||||
load_data, &http_state, None,
|
||||
let mut response = load::<MockRequest, TestProvider>(
|
||||
load_data, &ui_provider, &http_state, None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
&CancellationListener::new(None))
|
||||
|
@ -620,10 +704,11 @@ fn test_load_should_decode_the_response_as_gzip_when_response_headers_have_conte
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let mut response = load::<MockRequest>(
|
||||
let mut response = load::<MockRequest, TestProvider>(
|
||||
load_data,
|
||||
&http_state,
|
||||
&ui_provider, &http_state,
|
||||
None, &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
&CancellationListener::new(None))
|
||||
|
@ -663,9 +748,10 @@ fn test_load_doesnt_send_request_body_on_any_redirect() {
|
|||
load_data.data = Some(<[_]>::to_vec("Body on POST!".as_bytes()));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertMustHaveBodyRequest>(
|
||||
load_data, &http_state,
|
||||
let _ = load::<AssertMustHaveBodyRequest, TestProvider>(
|
||||
load_data, &ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -692,9 +778,10 @@ fn test_load_doesnt_add_host_to_sts_list_when_url_is_http_even_if_sts_headers_ar
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -723,9 +810,10 @@ fn test_load_adds_host_to_sts_list_when_url_is_https_and_sts_headers_are_present
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -752,13 +840,14 @@ fn test_load_sets_cookies_in_the_resource_manager_when_it_get_set_cookie_header_
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
assert_cookie_for_domain(http_state.cookie_jar.clone(), "http://mozilla.com", "");
|
||||
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let _ = load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -775,6 +864,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re
|
|||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
{
|
||||
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
|
||||
|
@ -790,7 +880,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(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: cookie,
|
||||
body: <[_]>::to_vec(&*load_data.data.unwrap())
|
||||
|
@ -802,7 +892,7 @@ fn test_load_sets_requests_cookies_header_for_url_by_getting_cookies_from_the_re
|
|||
fn test_load_sends_secure_cookie_if_http_changed_to_https_due_to_entry_in_hsts_store() {
|
||||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
let secured_url = Url::parse("https://mozilla.com").unwrap();
|
||||
|
||||
let ui_provider = TestProvider::new();
|
||||
let http_state = HttpState::new();
|
||||
{
|
||||
let mut hsts_list = http_state.hsts_list.write().unwrap();
|
||||
|
@ -832,8 +922,8 @@ fn test_load_sends_secure_cookie_if_http_changed_to_https_due_to_entry_in_hsts_s
|
|||
let mut headers = Headers::new();
|
||||
headers.set_raw("Cookie".to_owned(), vec![<[_]>::to_vec("mozillaIs=theBest".as_bytes())]);
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(
|
||||
load_data.clone(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: headers,
|
||||
body: <[_]>::to_vec(&*load_data.data.unwrap())
|
||||
|
@ -845,6 +935,7 @@ fn test_load_sends_cookie_if_nonhttp() {
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
{
|
||||
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
|
||||
|
@ -863,8 +954,8 @@ fn test_load_sends_cookie_if_nonhttp() {
|
|||
let mut headers = Headers::new();
|
||||
headers.set_raw("Cookie".to_owned(), vec![<[_]>::to_vec("mozillaIs=theBest".as_bytes())]);
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(
|
||||
load_data.clone(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: headers,
|
||||
body: <[_]>::to_vec(&*load_data.data.unwrap())
|
||||
|
@ -889,10 +980,11 @@ fn test_cookie_set_with_httponly_should_not_be_available_using_getcookiesforurl(
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
let _ = load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -918,10 +1010,11 @@ fn test_when_cookie_received_marked_secure_is_ignored_for_http() {
|
|||
}
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let load_data = LoadData::new(LoadContext::Browsing, Url::parse("http://mozilla.com").unwrap(), None);
|
||||
let _ = load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -937,6 +1030,7 @@ fn test_when_cookie_set_marked_httpsonly_secure_isnt_sent_on_http_request() {
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
{
|
||||
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
|
||||
|
@ -954,8 +1048,8 @@ fn test_when_cookie_set_marked_httpsonly_secure_isnt_sent_on_http_request() {
|
|||
|
||||
assert_cookie_for_domain(http_state.cookie_jar.clone(), "https://mozilla.com", "mozillaIs=theBest");
|
||||
|
||||
let _ = load::<AssertRequestMustNotIncludeHeaders>(
|
||||
load_data.clone(), &http_state, None,
|
||||
let _ = load::<AssertRequestMustNotIncludeHeaders, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state, None,
|
||||
&AssertMustNotIncludeHeadersRequestFactory {
|
||||
headers_not_expected: vec!["Cookie".to_owned()],
|
||||
body: <[_]>::to_vec(&*load_data.data.unwrap())
|
||||
|
@ -974,8 +1068,9 @@ fn test_load_sets_content_length_to_length_of_request_body() {
|
|||
content_len_headers.set(ContentLength(content.as_bytes().len() as u64));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(load_data.clone(), &http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data.clone(), &ui_provider, &http_state,
|
||||
None, &AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: content_len_headers,
|
||||
body: <[_]>::to_vec(&*load_data.data.unwrap())
|
||||
|
@ -996,9 +1091,10 @@ fn test_load_uses_explicit_accept_from_headers_in_load_data() {
|
|||
load_data.headers.set(Accept(vec![text_html.clone()]));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: accept_headers,
|
||||
|
@ -1022,9 +1118,10 @@ fn test_load_sets_default_accept_to_html_xhtml_xml_and_then_anything_else() {
|
|||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: accept_headers,
|
||||
|
@ -1044,9 +1141,10 @@ fn test_load_uses_explicit_accept_encoding_from_load_data_headers() {
|
|||
load_data.headers.set(AcceptEncoding(vec![qitem(Encoding::Chunked)]));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: accept_encoding_headers,
|
||||
|
@ -1067,9 +1165,10 @@ fn test_load_sets_default_accept_encoding_to_gzip_and_deflate() {
|
|||
load_data.data = Some(<[_]>::to_vec("Yay!".as_bytes()));
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: accept_encoding_headers,
|
||||
|
@ -1100,8 +1199,9 @@ fn test_load_errors_when_there_a_redirect_loop() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data, &http_state, None, &Factory,
|
||||
match load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, None, &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) {
|
||||
Err(LoadError::InvalidRedirect(_, msg)) => {
|
||||
assert_eq!(msg, "redirect loop");
|
||||
|
@ -1130,8 +1230,9 @@ fn test_load_errors_when_there_is_too_many_redirects() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data, &http_state, None, &Factory,
|
||||
match load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, None, &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) {
|
||||
Err(LoadError::MaxRedirects(url)) => {
|
||||
assert_eq!(url.domain().unwrap(), "mozilla.com")
|
||||
|
@ -1168,8 +1269,9 @@ fn test_load_follows_a_redirect() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data, &http_state, None, &Factory,
|
||||
match load::<MockRequest, TestProvider>(load_data, &ui_provider, &http_state, None, &Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) {
|
||||
Err(e) => panic!("expected to follow a redirect {:?}", e),
|
||||
Ok(mut lr) => {
|
||||
|
@ -1195,9 +1297,10 @@ fn test_load_errors_when_scheme_is_not_http_or_https() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
match load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&DontConnectFactory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -1213,9 +1316,10 @@ fn test_load_errors_when_viewing_source_and_inner_url_scheme_is_not_http_or_http
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
match load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&DontConnectFactory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -1254,9 +1358,10 @@ fn test_load_errors_when_cancelled() {
|
|||
let url = Url::parse("https://mozilla.com").unwrap();
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<MockRequest>(load_data,
|
||||
&http_state,
|
||||
match load::<MockRequest, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -1301,6 +1406,7 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url_x.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
{
|
||||
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
|
||||
|
@ -1322,8 +1428,8 @@ fn test_redirect_from_x_to_y_provides_y_cookies_from_y() {
|
|||
cookie_jar.push(cookie_y, CookieSource::HTTP);
|
||||
}
|
||||
|
||||
match load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
match load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -1368,9 +1474,10 @@ fn test_redirect_from_x_to_x_provides_x_with_cookie_from_first_response() {
|
|||
let load_data = LoadData::new(LoadContext::Browsing, url.clone(), None);
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
match load::<AssertRequestMustIncludeHeaders>(load_data,
|
||||
&http_state,
|
||||
match load::<AssertRequestMustIncludeHeaders, TestProvider>(load_data,
|
||||
&ui_provider, &http_state,
|
||||
None,
|
||||
&Factory,
|
||||
DEFAULT_USER_AGENT.to_owned(),
|
||||
|
@ -1388,6 +1495,7 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
|
|||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider::new();
|
||||
|
||||
let auth_entry = AuthCacheEntry {
|
||||
user_name: "username".to_owned(),
|
||||
|
@ -1410,10 +1518,42 @@ fn test_if_auth_creds_not_in_url_but_in_cache_it_sets_it() {
|
|||
)
|
||||
);
|
||||
|
||||
let _ = load::<AssertRequestMustIncludeHeaders>(
|
||||
load_data.clone(), &http_state,
|
||||
let _ = load::<AssertRequestMustIncludeHeaders, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state,
|
||||
None, &AssertMustIncludeHeadersRequestFactory {
|
||||
expected_headers: auth_header,
|
||||
body: <[_]>::to_vec(&[])
|
||||
}, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_auth_ui_sets_header_on_401() {
|
||||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
let http_state = HttpState::new();
|
||||
let ui_provider = TestProvider { username: "test".to_owned(), password: "test".to_owned() };
|
||||
|
||||
let mut auth_header = Headers::new();
|
||||
|
||||
auth_header.set(
|
||||
Authorization(
|
||||
Basic {
|
||||
username: "test".to_owned(),
|
||||
password: Some("test".to_owned())
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url, None);
|
||||
|
||||
match load::<AssertAuthHeaderRequest, TestProvider>(
|
||||
load_data.clone(), &ui_provider, &http_state,
|
||||
None, &AssertAuthHeaderRequestFactory {
|
||||
expected_headers: auth_header,
|
||||
body: <[_]>::to_vec(&[])
|
||||
}, DEFAULT_USER_AGENT.to_owned(), &CancellationListener::new(None)) {
|
||||
Err(e) => panic!("response contained error {:?}", e),
|
||||
Ok(response) => {
|
||||
assert_eq!(response.metadata.status, Some(RawStatus(200, Cow::Borrowed("Ok"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue