use actix_rt::task::JoinError; use awc::Client; use http_signature_normalization_actix::prelude::*; use sha2::{Digest, Sha256}; use std::time::SystemTime; use tracing::{error, info}; use tracing_error::ErrorLayer; use tracing_subscriber::{layer::SubscriberExt, EnvFilter}; async fn request(config: Config) -> Result<(), Box> { let digest = Sha256::new(); let mut response = Client::default() .post("http://127.0.0.1:8010/") .append_header(("User-Agent", "Actix Web")) .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| { info!("Signing String\n{}", s); Ok(base64::encode(s)) as Result<_, MyError> }) .await? .send() .await .map_err(|e| { error!("Error, {}", e); MyError::SendRequest })?; let body = response.body().await.map_err(|e| { error!("Error, {}", e); MyError::Body })?; info!("{:?}", body); Ok(()) } #[actix_rt::main] async fn main() -> Result<(), Box> { let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); let subscriber = tracing_subscriber::Registry::default() .with(env_filter) .with(ErrorLayer::default()) .with(tracing_subscriber::fmt::layer()); tracing::subscriber::set_global_default(subscriber)?; let config = Config::default().require_header("accept").require_digest(); request(config.clone()).await?; request(config.mastodon_compat()).await?; Ok(()) } #[derive(Debug, thiserror::Error)] pub enum MyError { #[error("Failed to create signing string, {0}")] Convert(#[from] PrepareSignError), #[error("Failed to create header, {0}")] Header(#[from] InvalidHeaderValue), #[error("Failed to send request")] SendRequest, #[error("Failed to retrieve request body")] Body, #[error("Blocking operation was canceled")] Canceled, } impl From for MyError { fn from(_: JoinError) -> Self { MyError::Canceled } }