#![doc = include_str!("../examples/add_authorization.rs")]
use std::task::{Context, Poll};
use base64::{Engine, engine::general_purpose::STANDARD as BASE64};
use http::header::{HeaderValue, InvalidHeaderValue};
use tower_layer::Layer;
use tower_service::Service;
#[doc = include_str!("../examples/add_authorization.rs")]
#[derive(Debug, Clone)]
pub struct AddAuthorizationLayer {
value: HeaderValue,
}
#[derive(Debug, Clone)]
pub struct AddAuthorizationService<S> {
inner: S,
value: HeaderValue,
}
impl AddAuthorizationLayer {
pub fn basic(
username: impl AsRef<str>,
password: impl AsRef<str>,
) -> Result<Self, InvalidHeaderValue> {
let encoded = BASE64.encode([username.as_ref(), ":", password.as_ref()].concat());
Ok(Self {
value: ["Basic ", encoded.as_ref()].concat().parse()?,
})
}
pub fn bearer(token: impl AsRef<str>) -> Result<Self, InvalidHeaderValue> {
Ok(Self {
value: ["Bearer ", token.as_ref()].concat().parse()?,
})
}
#[must_use]
pub fn set_sensitive(mut self, sensitive: bool) -> Self {
self.value.set_sensitive(sensitive);
self
}
}
impl<S> Layer<S> for AddAuthorizationLayer {
type Service = AddAuthorizationService<S>;
fn layer(&self, inner: S) -> Self::Service {
AddAuthorizationService {
inner,
value: self.value.clone(),
}
}
}
impl<S> AddAuthorizationService<S> {
pub fn basic(
inner: S,
username: impl AsRef<str>,
password: impl AsRef<str>,
) -> Result<Self, InvalidHeaderValue> {
AddAuthorizationLayer::basic(username, password).map(|layer| layer.layer(inner))
}
pub fn bearer(inner: S, token: impl AsRef<str>) -> Result<Self, InvalidHeaderValue> {
AddAuthorizationLayer::bearer(token).map(|layer| layer.layer(inner))
}
#[must_use]
pub fn set_sensitive(mut self, sensitive: bool) -> Self {
self.value.set_sensitive(sensitive);
self
}
}
impl<S> Service<reqwest::Request> for AddAuthorizationService<S>
where
S: Service<reqwest::Request, Response = reqwest::Response>,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
#[inline]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, mut req: reqwest::Request) -> Self::Future {
req.headers_mut()
.insert(http::header::AUTHORIZATION, self.value.clone());
self.inner.call(req)
}
}