Skip to content

Commit

Permalink
support url with authority (#735)
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar authored Dec 11, 2019
1 parent d2cbc8e commit 6334345
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ matrix:
script: cargo build --target "$TARGET" --no-default-features

# minimum version
- rust: 1.34.0
- rust: 1.36.0
script: cargo build

sudo: false
Expand Down
62 changes: 58 additions & 4 deletions src/async_impl/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,18 @@ impl Request {

impl RequestBuilder {
pub(super) fn new(client: Client, request: ::Result<Request>) -> RequestBuilder {
RequestBuilder {
client,
request,
let mut builder = RequestBuilder { client, request };

let auth = builder
.request
.as_mut()
.ok()
.and_then(|req| extract_authority(&mut req.url));

if let Some((username, password)) = auth {
builder.basic_auth(username, password)
} else {
builder
}
}

Expand Down Expand Up @@ -170,7 +179,7 @@ impl RequestBuilder {
Some(password) => format!("{}:{}", username, password),
None => format!("{}:", username)
};
let header_value = format!("Basic {}", encode(&auth));
let header_value = format!("Basic {}", encode(&dbg!(auth)));
self.header(::header::AUTHORIZATION, &*header_value)
}

Expand Down Expand Up @@ -424,6 +433,37 @@ pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
}
}


/// Check the request URL for a "username:password" type authority, and if
/// found, remove it from the URL and return it.
pub(crate) fn extract_authority(url: &mut Url) -> Option<(String, Option<String>)> {
use url::percent_encoding::percent_decode;

if url.has_authority() {
let username: String = percent_decode(url.username().as_bytes())
.decode_utf8()
.ok()?
.into();
let password = url.password().and_then(|pass| {
percent_decode(pass.as_bytes())
.decode_utf8()
.ok()
.map(String::from)
});
if !username.is_empty() || password.is_some() {
url
.set_username("")
.expect("has_authority means set_username shouldn't fail");
url
.set_password(None)
.expect("has_authority means set_password shouldn't fail");
return Some((username, password))
}
}

None
}

#[cfg(test)]
mod tests {
use super::Client;
Expand Down Expand Up @@ -536,6 +576,20 @@ mod tests {
assert_eq!(req.url().as_str(), "https://google.com/");
}

#[test]
fn convert_url_authority_into_basic_auth() {
let client = Client::new();
let some_url = "https://Aladdin:open sesame@localhost/";

let req = client
.get(some_url)
.build()
.expect("request build");

assert_eq!(req.url().as_str(), "https://localhost/");
assert_eq!(req.headers()["authorization"], "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
}

/*
use {body, Method};
use super::Client;
Expand Down
29 changes: 26 additions & 3 deletions src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,18 @@ impl Request {

impl RequestBuilder {
pub(crate) fn new(client: Client, request: ::Result<Request>) -> RequestBuilder {
RequestBuilder {
client,
request,
let mut builder = RequestBuilder { client, request };

let auth = builder
.request
.as_mut()
.ok()
.and_then(|req| async_impl::request::extract_authority(req.url_mut()));

if let Some((username, password)) = auth {
builder.basic_auth(username, password)
} else {
builder
}
}

Expand Down Expand Up @@ -883,4 +892,18 @@ mod tests {
assert_eq!(req.url().query(), None);
assert_eq!(req.url().as_str(), "https://google.com/");
}

#[test]
fn convert_url_authority_into_basic_auth() {
let client = Client::new();
let some_url = "https://Aladdin:open sesame@localhost/";

let req = client
.get(some_url)
.build()
.expect("request build");

assert_eq!(req.url().as_str(), "https://localhost/");
assert_eq!(req.headers()["authorization"], "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
}
}

0 comments on commit 6334345

Please sign in to comment.