mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-22 01:11:00 +00:00
Run signature creation in spawn_blocking
Also move -reqwest fully to async trait
This commit is contained in:
parent
c7cb3ce602
commit
ac25b1d951
3 changed files with 120 additions and 116 deletions
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "http-signature-normalization-reqwest"
|
name = "http-signature-normalization-reqwest"
|
||||||
description = "An HTTP Signatures library that leaves the signing to you"
|
description = "An HTTP Signatures library that leaves the signing to you"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
authors = ["asonix <asonix@asonix.dog>"]
|
authors = ["asonix <asonix@asonix.dog>"]
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -22,6 +22,7 @@ name = "client"
|
||||||
required-features = ["sha-2"]
|
required-features = ["sha-2"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1.71"
|
||||||
base64 = { version = "0.13", optional = true }
|
base64 = { version = "0.13", optional = true }
|
||||||
http-signature-normalization = { version = "0.7.0", path = ".." }
|
http-signature-normalization = { version = "0.7.0", path = ".." }
|
||||||
httpdate = "1.0.2"
|
httpdate = "1.0.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{Config, Sign, SignError};
|
use crate::{Config, Sign, SignError};
|
||||||
use reqwest::{Body, Request, RequestBuilder};
|
use reqwest::{Body, Request, RequestBuilder};
|
||||||
use std::{fmt::Display, future::Future, pin::Pin};
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[cfg(feature = "sha-2")]
|
#[cfg(feature = "sha-2")]
|
||||||
mod sha2;
|
mod sha2;
|
||||||
|
@ -21,58 +21,58 @@ pub trait DigestCreate {
|
||||||
/// It generates HTTP Signatures after the Digest header has been added, in order to have
|
/// It generates HTTP Signatures after the Digest header has been added, in order to have
|
||||||
/// verification that the body has not been tampered with, or that the request can't be replayed by
|
/// verification that the body has not been tampered with, or that the request can't be replayed by
|
||||||
/// a malicious entity
|
/// a malicious entity
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait SignExt: Sign {
|
pub trait SignExt: Sign {
|
||||||
fn authorization_signature_with_digest<F, E, K, D, V>(
|
async fn authorization_signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
digest: D,
|
digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
fn signature_with_digest<F, E, K, D, V>(
|
async fn signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
digest: D,
|
digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl SignExt for RequestBuilder {
|
impl SignExt for RequestBuilder {
|
||||||
fn authorization_signature_with_digest<F, E, K, D, V>(
|
async fn authorization_signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
mut digest: D,
|
mut digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized,
|
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
|
||||||
let (v, digest) = tokio::task::spawn_blocking(move || {
|
let (v, digest) = tokio::task::spawn_blocking(move || {
|
||||||
let digest = digest.compute(v.as_ref());
|
let digest = digest.compute(v.as_ref());
|
||||||
(v, digest)
|
(v, digest)
|
||||||
|
@ -82,31 +82,29 @@ impl SignExt for RequestBuilder {
|
||||||
|
|
||||||
let mut req = self
|
let mut req = self
|
||||||
.header("Digest", format!("{}={}", D::NAME, digest))
|
.header("Digest", format!("{}={}", D::NAME, digest))
|
||||||
.authorization_signature(&config, key_id, f)?;
|
.authorization_signature(&config, key_id, f)
|
||||||
|
.await?;
|
||||||
|
|
||||||
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
||||||
|
|
||||||
Ok(req)
|
Ok(req)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature_with_digest<F, E, K, D, V>(
|
async fn signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
mut digest: D,
|
mut digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized,
|
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
|
||||||
let (v, digest) = tokio::task::spawn_blocking(move || {
|
let (v, digest) = tokio::task::spawn_blocking(move || {
|
||||||
let digest = digest.compute(v.as_ref());
|
let digest = digest.compute(v.as_ref());
|
||||||
(v, digest)
|
(v, digest)
|
||||||
|
@ -116,12 +114,12 @@ impl SignExt for RequestBuilder {
|
||||||
|
|
||||||
let mut req = self
|
let mut req = self
|
||||||
.header("Digest", format!("{}={}", D::NAME, digest))
|
.header("Digest", format!("{}={}", D::NAME, digest))
|
||||||
.signature(&config, key_id, f)?;
|
.signature(&config, key_id, f)
|
||||||
|
.await?;
|
||||||
|
|
||||||
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
||||||
|
|
||||||
Ok(req)
|
Ok(req)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,26 +128,26 @@ mod middleware {
|
||||||
use super::{Config, DigestCreate, Sign, SignError, SignExt};
|
use super::{Config, DigestCreate, Sign, SignError, SignExt};
|
||||||
use reqwest::{Body, Request};
|
use reqwest::{Body, Request};
|
||||||
use reqwest_middleware::RequestBuilder;
|
use reqwest_middleware::RequestBuilder;
|
||||||
use std::{fmt::Display, future::Future, pin::Pin};
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl SignExt for RequestBuilder {
|
impl SignExt for RequestBuilder {
|
||||||
fn authorization_signature_with_digest<F, E, K, D, V>(
|
async fn authorization_signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
mut digest: D,
|
mut digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
|
||||||
let (v, digest) = tokio::task::spawn_blocking(move || {
|
let (v, digest) = tokio::task::spawn_blocking(move || {
|
||||||
let digest = digest.compute(v.as_ref());
|
let digest = digest.compute(v.as_ref());
|
||||||
(v, digest)
|
(v, digest)
|
||||||
|
@ -159,31 +157,30 @@ mod middleware {
|
||||||
|
|
||||||
let mut req = self
|
let mut req = self
|
||||||
.header("Digest", format!("{}={}", D::NAME, digest))
|
.header("Digest", format!("{}={}", D::NAME, digest))
|
||||||
.authorization_signature(&config, key_id, f)?;
|
.authorization_signature(&config, key_id, f)
|
||||||
|
.await?;
|
||||||
|
|
||||||
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
||||||
|
|
||||||
Ok(req)
|
Ok(req)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature_with_digest<F, E, K, D, V>(
|
async fn signature_with_digest<F, E, K, D, V>(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
mut digest: D,
|
mut digest: D,
|
||||||
v: V,
|
v: V,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<Request, E>> + Send>>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display + Send + 'static,
|
K: Display + Send + 'static,
|
||||||
D: DigestCreate + Send + 'static,
|
D: DigestCreate + Send + 'static,
|
||||||
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
V: AsRef<[u8]> + Into<Body> + Send + 'static,
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
|
||||||
let (v, digest) = tokio::task::spawn_blocking(move || {
|
let (v, digest) = tokio::task::spawn_blocking(move || {
|
||||||
let digest = digest.compute(v.as_ref());
|
let digest = digest.compute(v.as_ref());
|
||||||
(v, digest)
|
(v, digest)
|
||||||
|
@ -193,12 +190,12 @@ mod middleware {
|
||||||
|
|
||||||
let mut req = self
|
let mut req = self
|
||||||
.header("Digest", format!("{}={}", D::NAME, digest))
|
.header("Digest", format!("{}={}", D::NAME, digest))
|
||||||
.signature(&config, key_id, f)?;
|
.signature(&config, key_id, f)
|
||||||
|
.await?;
|
||||||
|
|
||||||
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
*req.body_mut() = Some(Body::from(v.as_ref().to_vec()));
|
||||||
|
|
||||||
Ok(req)
|
Ok(req)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,10 @@ pub struct Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait implemented by the reqwest RequestBuilder type to add an HTTP Signature to the request
|
/// A trait implemented by the reqwest RequestBuilder type to add an HTTP Signature to the request
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait Sign {
|
pub trait Sign {
|
||||||
/// Add an Authorization Signature to the request
|
/// Add an Authorization Signature to the request
|
||||||
fn authorization_signature<F, E, K>(
|
async fn authorization_signature<F, E, K>(
|
||||||
self,
|
self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
|
@ -49,17 +50,17 @@ pub trait Sign {
|
||||||
) -> Result<Request, E>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display;
|
K: Display + Send;
|
||||||
|
|
||||||
/// Add a Signature to the request
|
/// Add a Signature to the request
|
||||||
fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
async fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display;
|
K: Display + Send;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -156,20 +157,21 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl Sign for RequestBuilder {
|
impl Sign for RequestBuilder {
|
||||||
fn authorization_signature<F, E, K>(
|
async fn authorization_signature<F, E, K>(
|
||||||
self,
|
self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<Request, E>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display,
|
K: Display + Send,
|
||||||
{
|
{
|
||||||
let mut request = self.build()?;
|
let mut request = self.build()?;
|
||||||
let signed = prepare(&mut request, config, key_id, f)?;
|
let signed = prepare(&mut request, config, key_id, f).await?;
|
||||||
|
|
||||||
let auth_header = signed.authorization_header();
|
let auth_header = signed.authorization_header();
|
||||||
request.headers_mut().insert(
|
request.headers_mut().insert(
|
||||||
|
@ -180,14 +182,14 @@ impl Sign for RequestBuilder {
|
||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
async fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display,
|
K: Display + Send,
|
||||||
{
|
{
|
||||||
let mut request = self.build()?;
|
let mut request = self.build()?;
|
||||||
let signed = prepare(&mut request, config, key_id, f)?;
|
let signed = prepare(&mut request, config, key_id, f).await?;
|
||||||
|
|
||||||
let sig_header = signed.signature_header();
|
let sig_header = signed.signature_header();
|
||||||
|
|
||||||
|
@ -200,11 +202,11 @@ impl Sign for RequestBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare<F, E, K>(req: &mut Request, config: &Config, key_id: K, f: F) -> Result<Signed, E>
|
async fn prepare<F, E, K>(req: &mut Request, config: &Config, key_id: K, f: F) -> Result<Signed, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError>,
|
E: From<SignError> + Send + 'static,
|
||||||
K: Display,
|
K: Display + Send,
|
||||||
{
|
{
|
||||||
if config.set_date && !req.headers().contains_key("date") {
|
if config.set_date && !req.headers().contains_key("date") {
|
||||||
req.headers_mut().insert(
|
req.headers_mut().insert(
|
||||||
|
@ -246,7 +248,10 @@ where
|
||||||
.begin_sign(req.method().as_str(), &path_and_query, bt)
|
.begin_sign(req.method().as_str(), &path_and_query, bt)
|
||||||
.map_err(SignError::from)?;
|
.map_err(SignError::from)?;
|
||||||
|
|
||||||
let signed = unsigned.sign(key_id.to_string(), f)?;
|
let key_string = key_id.to_string();
|
||||||
|
let signed = tokio::task::spawn_blocking(move || unsigned.sign(key_string, f))
|
||||||
|
.await
|
||||||
|
.map_err(|_| SignError::Canceled)??;
|
||||||
Ok(signed)
|
Ok(signed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,20 +262,21 @@ mod middleware {
|
||||||
use reqwest_middleware::RequestBuilder;
|
use reqwest_middleware::RequestBuilder;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl Sign for RequestBuilder {
|
impl Sign for RequestBuilder {
|
||||||
fn authorization_signature<F, E, K>(
|
async fn authorization_signature<F, E, K>(
|
||||||
self,
|
self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<Request, E>
|
) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display,
|
K: Display + Send,
|
||||||
{
|
{
|
||||||
let mut request = self.build()?;
|
let mut request = self.build()?;
|
||||||
let signed = prepare(&mut request, config, key_id, f)?;
|
let signed = prepare(&mut request, config, key_id, f).await?;
|
||||||
|
|
||||||
let auth_header = signed.authorization_header();
|
let auth_header = signed.authorization_header();
|
||||||
request.headers_mut().insert(
|
request.headers_mut().insert(
|
||||||
|
@ -281,14 +287,14 @@ mod middleware {
|
||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
async fn signature<F, E, K>(self, config: &Config, key_id: K, f: F) -> Result<Request, E>
|
||||||
where
|
where
|
||||||
F: FnOnce(&str) -> Result<String, E>,
|
F: FnOnce(&str) -> Result<String, E> + Send + 'static,
|
||||||
E: From<SignError> + From<reqwest::Error>,
|
E: From<SignError> + From<reqwest::Error> + Send + 'static,
|
||||||
K: Display,
|
K: Display + Send,
|
||||||
{
|
{
|
||||||
let mut request = self.build()?;
|
let mut request = self.build()?;
|
||||||
let signed = prepare(&mut request, config, key_id, f)?;
|
let signed = prepare(&mut request, config, key_id, f).await?;
|
||||||
|
|
||||||
let sig_header = signed.signature_header();
|
let sig_header = signed.signature_header();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue