mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-22 01:11:00 +00:00
Update actix client to automatically set Date header in masto compat
This commit is contained in:
parent
82b59317cb
commit
efc55fd9a1
4 changed files with 36 additions and 13 deletions
|
@ -2,7 +2,6 @@ use actix_rt::task::JoinError;
|
||||||
use awc::Client;
|
use awc::Client;
|
||||||
use http_signature_normalization_actix::prelude::*;
|
use http_signature_normalization_actix::prelude::*;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::time::SystemTime;
|
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
use tracing_error::ErrorLayer;
|
use tracing_error::ErrorLayer;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
||||||
|
@ -14,7 +13,6 @@ async fn request(config: Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.post("http://127.0.0.1:8010/")
|
.post("http://127.0.0.1:8010/")
|
||||||
.append_header(("User-Agent", "Actix Web"))
|
.append_header(("User-Agent", "Actix Web"))
|
||||||
.append_header(("Accept", "text/plain"))
|
.append_header(("Accept", "text/plain"))
|
||||||
.insert_header(actix_web::http::header::Date(SystemTime::now().into()))
|
|
||||||
.signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| {
|
.signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| {
|
||||||
info!("Signing String\n{}", s);
|
info!("Signing String\n{}", s);
|
||||||
Ok(base64::encode(s)) as Result<_, MyError>
|
Ok(base64::encode(s)) as Result<_, MyError>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_http::{header::InvalidHeaderValue};
|
use actix_http::header::InvalidHeaderValue;
|
||||||
use actix_rt::task::JoinError;
|
use actix_rt::task::JoinError;
|
||||||
use awc::ClientRequest;
|
use awc::ClientRequest;
|
||||||
use std::{fmt::Display, future::Future, pin::Pin};
|
use std::{fmt::Display, future::Future, pin::Pin};
|
||||||
|
|
|
@ -273,6 +273,9 @@ pub struct Config {
|
||||||
|
|
||||||
/// Whether to set the Host header
|
/// Whether to set the Host header
|
||||||
set_host: bool,
|
set_host: bool,
|
||||||
|
|
||||||
|
/// Whether to set the Date header
|
||||||
|
set_date: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
|
@ -324,17 +327,21 @@ mod client {
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
/// An error when preparing to sign a request
|
/// An error when preparing to sign a request
|
||||||
pub enum PrepareSignError {
|
pub enum PrepareSignError {
|
||||||
#[error("Failed to read header, {0}")]
|
#[error("Failed to read header")]
|
||||||
/// An error occurred when reading the request's headers
|
/// An error occurred when reading the request's headers
|
||||||
Header(#[from] ToStrError),
|
Header(#[from] ToStrError),
|
||||||
|
|
||||||
#[error("{0}")]
|
#[error("Missing required header")]
|
||||||
/// Some headers were marked as required, but are missing
|
/// Some headers were marked as required, but are missing
|
||||||
RequiredError(#[from] RequiredError),
|
RequiredError(#[from] RequiredError),
|
||||||
|
|
||||||
#[error("No host provided for URL, {0}")]
|
#[error("No host provided for URL, {0}")]
|
||||||
/// Missing host
|
/// Missing host
|
||||||
Host(String),
|
Host(String),
|
||||||
|
|
||||||
|
#[error("Failed to set header")]
|
||||||
|
/// Invalid Date header
|
||||||
|
InvalidHeader(#[from] actix_http::header::InvalidHeaderValue),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +428,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config,
|
config: self.config,
|
||||||
set_host: true,
|
set_host: true,
|
||||||
|
set_date: self.set_date,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +440,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.mastodon_compat(),
|
config: self.config.mastodon_compat(),
|
||||||
set_host: true,
|
set_host: true,
|
||||||
|
set_date: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +451,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.require_digest(),
|
config: self.config.require_digest(),
|
||||||
set_host: self.set_host,
|
set_host: self.set_host,
|
||||||
|
set_date: self.set_date,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,6 +463,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.dont_use_created_field(),
|
config: self.config.dont_use_created_field(),
|
||||||
set_host: self.set_host,
|
set_host: self.set_host,
|
||||||
|
set_date: self.set_date,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +472,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.set_expiration(expires_after),
|
config: self.config.set_expiration(expires_after),
|
||||||
set_host: self.set_host,
|
set_host: self.set_host,
|
||||||
|
set_date: self.set_date,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +481,7 @@ impl Config {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.require_header(header),
|
config: self.config.require_header(header),
|
||||||
set_host: self.set_host,
|
set_host: self.set_host,
|
||||||
|
set_date: self.set_date,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use actix_http::{header::InvalidHeaderValue};
|
|
||||||
use awc::ClientRequest;
|
|
||||||
use actix_rt::task::JoinError;
|
|
||||||
use std::{fmt::Display, future::Future, pin::Pin};
|
|
||||||
|
|
||||||
use crate::{create::Signed, Config, PrepareSignError, Sign};
|
use crate::{create::Signed, Config, PrepareSignError, Sign};
|
||||||
|
use actix_rt::task::JoinError;
|
||||||
|
use awc::{
|
||||||
|
http::header::{HttpDate, InvalidHeaderValue, TryIntoHeaderValue},
|
||||||
|
ClientRequest,
|
||||||
|
};
|
||||||
|
use std::{fmt::Display, future::Future, pin::Pin, time::SystemTime};
|
||||||
|
|
||||||
impl Sign for ClientRequest {
|
impl Sign for ClientRequest {
|
||||||
fn authorization_signature<F, E, K>(
|
fn authorization_signature<F, E, K>(
|
||||||
|
@ -24,7 +25,7 @@ impl Sign for ClientRequest {
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let signed = prepare(&self, &config, key_id, f).await?;
|
let signed = prepare(&mut self, &config, key_id, f).await?;
|
||||||
signed.authorization_header(self.headers_mut())?;
|
signed.authorization_header(self.headers_mut())?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
})
|
})
|
||||||
|
@ -48,7 +49,7 @@ impl Sign for ClientRequest {
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let signed = prepare(&self, &config, key_id, f).await?;
|
let signed = prepare(&mut self, &config, key_id, f).await?;
|
||||||
signed.signature_header(self.headers_mut())?;
|
signed.signature_header(self.headers_mut())?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
})
|
})
|
||||||
|
@ -56,7 +57,7 @@ impl Sign for ClientRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prepare<F, E, K>(
|
async fn prepare<F, E, K>(
|
||||||
request: &ClientRequest,
|
request: &mut ClientRequest,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
key_id: K,
|
key_id: K,
|
||||||
f: F,
|
f: F,
|
||||||
|
@ -66,6 +67,17 @@ where
|
||||||
E: From<JoinError> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
E: From<JoinError> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
||||||
K: Display,
|
K: Display,
|
||||||
{
|
{
|
||||||
|
if config.set_date {
|
||||||
|
if !request.headers().contains_key("date") {
|
||||||
|
request.headers_mut().insert(
|
||||||
|
actix_http::header::DATE,
|
||||||
|
HttpDate::from(SystemTime::now())
|
||||||
|
.try_into_value()
|
||||||
|
.expect("Date is valid"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut headers = request.headers().clone();
|
let mut headers = request.headers().clone();
|
||||||
if config.set_host {
|
if config.set_host {
|
||||||
let header_string = request
|
let header_string = request
|
||||||
|
|
Loading…
Reference in a new issue