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; | ||||
|   | ||||
| @@ -122,7 +122,19 @@ impl Request { | ||||
|  | ||||
| impl 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. | ||||
| @@ -872,4 +884,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=="); | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user