support url with authority (#736)
This commit is contained in:
@@ -112,7 +112,19 @@ impl Request {
|
||||
|
||||
impl RequestBuilder {
|
||||
pub(super) fn new(client: Client, request: crate::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
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a `Header` to this Request.
|
||||
@@ -430,6 +442,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 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;
|
||||
@@ -588,6 +631,20 @@ mod tests {
|
||||
assert!(clone.is_none());
|
||||
}
|
||||
|
||||
#[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;
|
||||
|
||||
Reference in New Issue
Block a user