http-signature-normalization-actix 0.3.0-alpha.2

An HTTP Signatures library that leaves the signing to you
Documentation
use actix_web::{
    client::ClientRequest,
    http::header::{InvalidHeaderValue, ToStrError},
};
use std::fmt::Display;

use crate::{create::Signed, Config, Sign};

impl Sign for ClientRequest {
    fn authorization_signature<F, E, K>(
        mut self,
        config: &Config,
        key_id: K,
        f: F,
    ) -> Result<Self, E>
    where
        F: FnOnce(&str) -> Result<String, E>,
        E: From<ToStrError> + From<InvalidHeaderValue>,
        K: Display,
    {
        let signed = prepare(&self, config, key_id, f)?;
        signed.authorization_header(self.headers_mut())?;
        Ok(self)
    }

    fn signature<F, E, K>(mut self, config: &Config, key_id: K, f: F) -> Result<Self, E>
    where
        F: FnOnce(&str) -> Result<String, E>,
        E: From<ToStrError> + From<InvalidHeaderValue>,
        K: Display,
    {
        let signed = prepare(&self, config, key_id, f)?;
        signed.signature_header(self.headers_mut())?;
        Ok(self)
    }
}

fn prepare<F, E, K>(request: &ClientRequest, config: &Config, key_id: K, f: F) -> Result<Signed, E>
where
    F: FnOnce(&str) -> Result<String, E>,
    E: From<ToStrError>,
    K: Display,
{
    let unsigned = config.begin_sign(
        request.get_method(),
        request.get_uri().path_and_query(),
        request.headers().clone(),
    )?;

    let key_id = key_id.to_string();

    let signed = unsigned.sign(key_id, f)?;

    Ok(signed)
}