mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-25 02:41:00 +00:00
Update actix examples with tracing
This commit is contained in:
parent
7b9aff925a
commit
11be605f5b
3 changed files with 86 additions and 21 deletions
|
@ -41,4 +41,5 @@ tracing-futures = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.1.0"
|
actix-rt = "2.1.0"
|
||||||
pretty_env_logger = "0.4"
|
tracing-actix-web = { version = "0.4.0-beta.12", git = "https://github.com/asonix/tracing-actix-web", branch = "asonix/root-span-expansion" }
|
||||||
|
tracing-subscriber = { version = "0.2", features = ["fmt"] }
|
||||||
|
|
|
@ -3,6 +3,9 @@ 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 std::time::SystemTime;
|
||||||
|
use tracing::{error, info};
|
||||||
|
use tracing_error::ErrorLayer;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
||||||
|
|
||||||
async fn request(config: Config) -> Result<(), Box<dyn std::error::Error>> {
|
async fn request(config: Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let digest = Sha256::new();
|
let digest = Sha256::new();
|
||||||
|
@ -13,30 +16,36 @@ async fn request(config: Config) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.append_header(("Accept", "text/plain"))
|
.append_header(("Accept", "text/plain"))
|
||||||
.insert_header(actix_web::http::header::Date(SystemTime::now().into()))
|
.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| {
|
||||||
println!("Signing String\n{}", s);
|
info!("Signing String\n{}", s);
|
||||||
Ok(base64::encode(s)) as Result<_, MyError>
|
Ok(base64::encode(s)) as Result<_, MyError>
|
||||||
})
|
})
|
||||||
.await?
|
.await?
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
eprintln!("Error, {}", e);
|
error!("Error, {}", e);
|
||||||
MyError::SendRequest
|
MyError::SendRequest
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let body = response.body().await.map_err(|e| {
|
let body = response.body().await.map_err(|e| {
|
||||||
eprintln!("Error, {}", e);
|
error!("Error, {}", e);
|
||||||
MyError::Body
|
MyError::Body
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
println!("{:?}", body);
|
info!("{:?}", body);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::env::set_var("RUST_LOG", "info");
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
||||||
pretty_env_logger::init();
|
|
||||||
|
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();
|
let config = Config::default().require_header("accept").require_digest();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use actix_web::{
|
use actix_web::{http::StatusCode, web, App, HttpRequest, HttpResponse, HttpServer, ResponseError};
|
||||||
http::StatusCode, middleware::Logger, web, App, HttpRequest, HttpResponse, HttpServer,
|
|
||||||
ResponseError,
|
|
||||||
};
|
|
||||||
use futures::future::{err, ok, Ready};
|
|
||||||
use http_signature_normalization_actix::prelude::*;
|
use http_signature_normalization_actix::prelude::*;
|
||||||
use log::info;
|
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::future::{ready, Ready};
|
||||||
|
use tracing::info;
|
||||||
|
use tracing_actix_web::TracingLogger;
|
||||||
|
use tracing_error::ErrorLayer;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct MyVerify;
|
struct MyVerify;
|
||||||
|
@ -23,21 +23,21 @@ impl SignatureVerify for MyVerify {
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
match algorithm {
|
match algorithm {
|
||||||
Some(Algorithm::Hs2019) => (),
|
Some(Algorithm::Hs2019) => (),
|
||||||
_ => return err(MyError::Algorithm),
|
_ => return ready(Err(MyError::Algorithm)),
|
||||||
};
|
};
|
||||||
|
|
||||||
if key_id != "my-key-id" {
|
if key_id != "my-key-id" {
|
||||||
return err(MyError::Key);
|
return ready(Err(MyError::Key));
|
||||||
}
|
}
|
||||||
|
|
||||||
let decoded = match base64::decode(&signature) {
|
let decoded = match base64::decode(&signature) {
|
||||||
Ok(decoded) => decoded,
|
Ok(decoded) => decoded,
|
||||||
Err(_) => return err(MyError::Decode),
|
Err(_) => return ready(Err(MyError::Decode)),
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("Signing String\n{}", signing_string);
|
info!("Signing String\n{}", signing_string);
|
||||||
|
|
||||||
ok(decoded == signing_string.as_bytes())
|
ready(Ok(decoded == signing_string.as_bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,14 @@ async fn index(
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::env::set_var("RUST_LOG", "info");
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
||||||
pretty_env_logger::init();
|
|
||||||
|
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();
|
let config = Config::default().require_header("accept").require_digest();
|
||||||
|
|
||||||
|
@ -62,7 +68,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(VerifyDigest::new(Sha256::new()).optional())
|
.wrap(VerifyDigest::new(Sha256::new()).optional())
|
||||||
.wrap(VerifySignature::new(MyVerify, config.clone()).optional())
|
.wrap(VerifySignature::new(MyVerify, config.clone()).optional())
|
||||||
.wrap(Logger::default())
|
.wrap(TracingLogger::<RootSpanBuilder>::new())
|
||||||
.route("/", web::post().to(index))
|
.route("/", web::post().to(index))
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8010")?
|
.bind("127.0.0.1:8010")?
|
||||||
|
@ -96,3 +102,52 @@ impl ResponseError for MyError {
|
||||||
HttpResponse::BadRequest().finish()
|
HttpResponse::BadRequest().finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tracing-actix-web + tracing-error WORKAROUND
|
||||||
|
|
||||||
|
use actix_web::{
|
||||||
|
dev::{ServiceRequest, ServiceResponse},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
use tracing::Span;
|
||||||
|
use tracing_actix_web::root_span;
|
||||||
|
|
||||||
|
pub struct RootSpanBuilder;
|
||||||
|
|
||||||
|
impl tracing_actix_web::RootSpanBuilder for RootSpanBuilder {
|
||||||
|
fn on_request_start(request: &ServiceRequest) -> Span {
|
||||||
|
root_span!(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_request_end<B>(span: Span, outcome: &Result<ServiceResponse<B>, Error>) {
|
||||||
|
match &outcome {
|
||||||
|
Ok(response) => {
|
||||||
|
if let Some(error) = response.response().error() {
|
||||||
|
handle_error(span, error)
|
||||||
|
} else {
|
||||||
|
span.record("http.status_code", &response.response().status().as_u16());
|
||||||
|
span.record("otel.status_code", &"OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => handle_error(span, error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_error(span: Span, error: &Error) {
|
||||||
|
let response_error = error.as_response_error();
|
||||||
|
|
||||||
|
let display = format!("{}", response_error);
|
||||||
|
let debug = format!("{:?}", response_error);
|
||||||
|
span.record("exception.message", &tracing::field::display(display));
|
||||||
|
span.record("exception.details", &tracing::field::display(debug));
|
||||||
|
|
||||||
|
let status_code = response_error.status_code();
|
||||||
|
span.record("http.status_code", &status_code.as_u16());
|
||||||
|
|
||||||
|
if status_code.is_client_error() {
|
||||||
|
span.record("otel.status_code", &"OK");
|
||||||
|
} else {
|
||||||
|
span.record("otel.status_code", &"ERROR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue