Skip to content

Commit

Permalink
Unify basic-auth header generation (#1726)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickelc committed Jan 13, 2023
1 parent 6df8858 commit 6f714f4
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 51 deletions.
13 changes: 1 addition & 12 deletions src/async_impl/request.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::convert::TryFrom;
use std::fmt;
use std::future::Future;
use std::io::Write;
use std::time::Duration;

use serde::Serialize;
Expand All @@ -16,7 +15,6 @@ use super::response::Response;
#[cfg(feature = "multipart")]
use crate::header::CONTENT_LENGTH;
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
use crate::util::base64;
use crate::{Method, Url};
use http::{request::Parts, Request as HttpRequest, Version};

Expand Down Expand Up @@ -251,16 +249,7 @@ impl RequestBuilder {
U: fmt::Display,
P: fmt::Display,
{
let mut header_value = b"Basic ".to_vec();
{
let mut encoder = base64::encoder(&mut header_value);
// The unwraps here are fine because Vec::write* is infallible.
write!(encoder, "{}:", username).unwrap();
if let Some(password) = password {
write!(encoder, "{}", password).unwrap();
}
}

let header_value = crate::util::basic_auth(username, password);
self.header_sensitive(crate::header::AUTHORIZATION, header_value, true)
}

Expand Down
9 changes: 2 additions & 7 deletions src/blocking/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use super::body::{self, Body};
use super::multipart;
use super::Client;
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
use crate::util::base64;
use crate::{async_impl, Method, Url};

/// A request which can be executed with `Client::execute()`.
Expand Down Expand Up @@ -266,12 +265,8 @@ impl RequestBuilder {
U: fmt::Display,
P: fmt::Display,
{
let auth = match password {
Some(password) => format!("{}:{}", username, password),
None => format!("{}:", username),
};
let header_value = format!("Basic {}", base64::encode(&auth));
self.header_sensitive(crate::header::AUTHORIZATION, &*header_value, true)
let header_value = crate::util::basic_auth(username, password);
self.header_sensitive(crate::header::AUTHORIZATION, header_value, true)
}

/// Enable HTTP bearer authentication.
Expand Down
8 changes: 1 addition & 7 deletions src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::net::SocketAddr;
use std::sync::Arc;

use crate::into_url::{IntoUrl, IntoUrlSealed};
use crate::util::base64;
use crate::Url;
use http::{header::HeaderValue, Uri};
use ipnet::IpNet;
Expand Down Expand Up @@ -763,12 +762,7 @@ impl fmt::Debug for Custom {
}

pub(crate) fn encode_basic_auth(username: &str, password: &str) -> HeaderValue {
let val = format!("{}:{}", username, password);
let mut header = format!("Basic {}", base64::encode(&val))
.parse::<HeaderValue>()
.expect("base64 is always valid HeaderValue");
header.set_sensitive(true);
header
crate::util::basic_auth(username, Some(password))
}

/// A helper trait to allow testing `Proxy::intercept` without having to
Expand Down
29 changes: 16 additions & 13 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
use crate::header::{Entry, HeaderMap, OccupiedEntry};
use crate::header::{Entry, HeaderMap, HeaderValue, OccupiedEntry};

pub(crate) mod base64 {
use std::io;

use base64::engine::GeneralPurpose;
pub fn basic_auth<U, P>(username: U, password: Option<P>) -> HeaderValue
where
U: std::fmt::Display,
P: std::fmt::Display,
{
use base64::prelude::BASE64_STANDARD;
use base64::write::EncoderWriter;
use std::io::Write;

if_hyper! {
pub fn encode<T: AsRef<[u8]>>(input: T) -> String {
use base64::Engine;
BASE64_STANDARD.encode(input)
let mut buf = b"Basic ".to_vec();
{
let mut encoder = EncoderWriter::new(&mut buf, &BASE64_STANDARD);
let _ = write!(encoder, "{}:", username);
if let Some(password) = password {
let _ = write!(encoder, "{}", password);
}
}

pub fn encoder<'a, W: io::Write>(delegate: W) -> EncoderWriter<'a, GeneralPurpose, W> {
EncoderWriter::new(delegate, &BASE64_STANDARD)
}
let mut header = HeaderValue::from_bytes(&buf).expect("base64 is always valid HeaderValue");
header.set_sensitive(true);
header
}

// xor-shift
Expand Down
13 changes: 1 addition & 12 deletions src/wasm/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::convert::TryFrom;
use std::fmt;
use std::io::Write;

use bytes::Bytes;
use http::{request::Parts, Method, Request as HttpRequest};
Expand All @@ -12,7 +11,6 @@ use web_sys::RequestCredentials;

use super::{Body, Client, Response};
use crate::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_TYPE};
use crate::util::base64;

/// A request which can be executed with `Client::execute()`.
pub struct Request {
Expand Down Expand Up @@ -214,16 +212,7 @@ impl RequestBuilder {
U: fmt::Display,
P: fmt::Display,
{
let mut header_value = b"Basic ".to_vec();
{
let mut encoder = base64::encoder(&mut header_value);
// The unwraps here are fine because Vec::write* is infallible.
write!(encoder, "{}:", username).unwrap();
if let Some(password) = password {
write!(encoder, "{}", password).unwrap();
}
}

let header_value = crate::util::basic_auth(username, password);
self.header(crate::header::AUTHORIZATION, header_value)
}

Expand Down

0 comments on commit 6f714f4

Please sign in to comment.