Skip to content

Commit

Permalink
401 authorization UI then restart request/save successful auth creds
Browse files Browse the repository at this point in the history
  • Loading branch information
ddefisher committed Apr 15, 2016
1 parent db4481b commit b0e1f10
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 61 deletions.
3 changes: 3 additions & 0 deletions components/net/Cargo.toml
Expand Up @@ -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"
Expand Down
56 changes: 53 additions & 3 deletions components/net/http_loader.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) => {
Expand Down Expand Up @@ -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.
Expand All @@ -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()));
}
Expand Down Expand Up @@ -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>() {
Expand Down
1 change: 1 addition & 0 deletions components/net/lib.rs
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions components/servo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions ports/cef/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions ports/gonk/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b0e1f10

Please sign in to comment.