|
| 1 | +use base64::prelude::*; |
| 2 | + |
1 | 3 | use futures::{ready, Stream};
|
2 | 4 | use hyper::{
|
3 | 5 | body::HttpBody,
|
@@ -133,6 +135,15 @@ impl ClientBuilder {
|
133 | 135 | Ok(self)
|
134 | 136 | }
|
135 | 137 |
|
| 138 | + /// Set the Authorization header with the calculated basic authentication value. |
| 139 | + pub fn basic_auth(self, username: &str, password: &str) -> Result<ClientBuilder> { |
| 140 | + let auth = format!("{}:{}", username, password); |
| 141 | + let encoded = BASE64_STANDARD.encode(auth); |
| 142 | + let value = format!("Basic {}", encoded); |
| 143 | + |
| 144 | + self.header("Authorization", &value) |
| 145 | + } |
| 146 | + |
136 | 147 | /// Set a read timeout for the underlying connection. There is no read timeout by default.
|
137 | 148 | pub fn read_timeout(mut self, read_timeout: Duration) -> ClientBuilder {
|
138 | 149 | self.read_timeout = Some(read_timeout);
|
@@ -599,3 +610,33 @@ mod private {
|
599 | 610 | pub trait Sealed {}
|
600 | 611 | impl<C> Sealed for ClientImpl<C> {}
|
601 | 612 | }
|
| 613 | + |
| 614 | +#[cfg(test)] |
| 615 | +mod tests { |
| 616 | + use crate::ClientBuilder; |
| 617 | + use hyper::http::HeaderValue; |
| 618 | + use test_case::test_case; |
| 619 | + |
| 620 | + #[test_case("user", "pass", "dXNlcjpwYXNz")] |
| 621 | + #[test_case("user1", "password123", "dXNlcjE6cGFzc3dvcmQxMjM=")] |
| 622 | + #[test_case("user2", "", "dXNlcjI6")] |
| 623 | + #[test_case("user@name", "pass#word!", "dXNlckBuYW1lOnBhc3Mjd29yZCE=")] |
| 624 | + #[test_case("user3", "my pass", "dXNlcjM6bXkgcGFzcw==")] |
| 625 | + #[test_case( |
| 626 | + "weird@-/:stuff", |
| 627 | + "goes@-/:here", |
| 628 | + "d2VpcmRALS86c3R1ZmY6Z29lc0AtLzpoZXJl" |
| 629 | + )] |
| 630 | + fn basic_auth_generates_correct_headers(username: &str, password: &str, expected: &str) { |
| 631 | + let builder = ClientBuilder::for_url("http://example.com") |
| 632 | + .expect("failed to build client") |
| 633 | + .basic_auth(username, password) |
| 634 | + .expect("failed to add authentication"); |
| 635 | + |
| 636 | + let actual = builder.headers.get("Authorization"); |
| 637 | + let expected = HeaderValue::from_str(format!("Basic {}", expected).as_str()) |
| 638 | + .expect("unable to create expected header"); |
| 639 | + |
| 640 | + assert_eq!(Some(&expected), actual); |
| 641 | + } |
| 642 | +} |
0 commit comments