Skip to content

Commit 526b03f

Browse files
authored
feat: Add basic_auth method to ClientBuilder (#88)
1 parent aed4e6b commit 526b03f

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

eventsource-client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pin-project = "1.0.10"
1818
tokio = { version = "1.17.0", features = ["time"] }
1919
hyper-timeout = "0.4.1"
2020
rand = "0.8.5"
21+
base64 = "0.22.1"
2122

2223
[dev-dependencies]
2324
env_logger = "0.10.0"

eventsource-client/src/client.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use base64::prelude::*;
2+
13
use futures::{ready, Stream};
24
use hyper::{
35
body::HttpBody,
@@ -133,6 +135,15 @@ impl ClientBuilder {
133135
Ok(self)
134136
}
135137

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+
136147
/// Set a read timeout for the underlying connection. There is no read timeout by default.
137148
pub fn read_timeout(mut self, read_timeout: Duration) -> ClientBuilder {
138149
self.read_timeout = Some(read_timeout);
@@ -599,3 +610,33 @@ mod private {
599610
pub trait Sealed {}
600611
impl<C> Sealed for ClientImpl<C> {}
601612
}
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

Comments
 (0)