simple_request/
request.rs

1use hyper::body::Bytes;
2#[cfg(feature = "basic-auth")]
3use hyper::header::HeaderValue;
4pub use http_body_util::Full;
5
6#[cfg(feature = "basic-auth")]
7use crate::Error;
8
9#[derive(Debug)]
10pub struct Request(pub(crate) hyper::Request<Full<Bytes>>);
11impl Request {
12  #[cfg(feature = "basic-auth")]
13  fn username_password_from_uri(&self) -> Result<(String, String), Error> {
14    if let Some(authority) = self.0.uri().authority() {
15      let authority = authority.as_str();
16      if authority.contains('@') {
17        // Decode the username and password from the URI
18        let mut userpass = authority.split('@').next().unwrap().to_string();
19
20        let mut userpass_iter = userpass.split(':');
21        let username = userpass_iter.next().unwrap().to_string();
22        let password = userpass_iter.next().map_or_else(String::new, str::to_string);
23        zeroize::Zeroize::zeroize(&mut userpass);
24
25        return Ok((username, password));
26      }
27    }
28    Err(Error::InvalidUri)
29  }
30
31  #[cfg(feature = "basic-auth")]
32  pub fn basic_auth(&mut self, username: &str, password: &str) {
33    use zeroize::Zeroize;
34    use base64ct::{Encoding, Base64};
35
36    let mut formatted = format!("{username}:{password}");
37    let mut encoded = Base64::encode_string(formatted.as_bytes());
38    formatted.zeroize();
39    self.0.headers_mut().insert(
40      hyper::header::AUTHORIZATION,
41      HeaderValue::from_str(&format!("Basic {encoded}")).unwrap(),
42    );
43    encoded.zeroize();
44  }
45
46  #[cfg(feature = "basic-auth")]
47  pub fn basic_auth_from_uri(&mut self) -> Result<(), Error> {
48    let (mut username, mut password) = self.username_password_from_uri()?;
49    self.basic_auth(&username, &password);
50
51    use zeroize::Zeroize;
52    username.zeroize();
53    password.zeroize();
54
55    Ok(())
56  }
57
58  #[cfg(feature = "basic-auth")]
59  pub fn with_basic_auth(&mut self) {
60    let _ = self.basic_auth_from_uri();
61  }
62}
63impl From<hyper::Request<Full<Bytes>>> for Request {
64  fn from(request: hyper::Request<Full<Bytes>>) -> Request {
65    Request(request)
66  }
67}