support url with authority (#736)
This commit is contained in:
@@ -112,7 +112,19 @@ impl Request {
|
|||||||
|
|
||||||
impl RequestBuilder {
|
impl RequestBuilder {
|
||||||
pub(super) fn new(client: Client, request: crate::Result<Request>) -> 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.
|
/// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Client;
|
use super::Client;
|
||||||
@@ -588,6 +631,20 @@ mod tests {
|
|||||||
assert!(clone.is_none());
|
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 {body, Method};
|
||||||
use super::Client;
|
use super::Client;
|
||||||
|
|||||||
@@ -122,7 +122,19 @@ impl Request {
|
|||||||
|
|
||||||
impl RequestBuilder {
|
impl RequestBuilder {
|
||||||
pub(crate) fn new(client: Client, request: crate::Result<Request>) -> RequestBuilder {
|
pub(crate) 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| async_impl::request::extract_authority(req.url_mut()));
|
||||||
|
|
||||||
|
if let Some((username, password)) = auth {
|
||||||
|
builder.basic_auth(username, password)
|
||||||
|
} else {
|
||||||
|
builder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a `Header` to this Request.
|
/// Add a `Header` to this Request.
|
||||||
@@ -872,4 +884,18 @@ mod tests {
|
|||||||
assert_eq!(req.url().query(), None);
|
assert_eq!(req.url().query(), None);
|
||||||
assert_eq!(req.url().as_str(), "https://google.com/");
|
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==");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user