use actix_web::body::{BoxBody, MessageBody}; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::http::header::{HeaderName, HeaderValue}; use actix_web::middleware::Next; use actix_web::{Error, HttpMessage}; pub use envelope::RequestId; pub use envelope::context::{request_id, resolve_request_id, with_request_id}; pub const REQUEST_ID_HEADER: HeaderName = HeaderName::from_static(envelope::REQUEST_ID_HEADER); pub async fn trace_request( request: ServiceRequest, next: Next, ) -> Result, Error> where B: MessageBody + 'static, { let request_id = RequestId::from_header(header(&request)); request.extensions_mut().insert(request_id.clone()); let response = envelope::context::with_request_id(Some(request_id.as_str()), next.call(request)).await?; let mut response = response.map_into_boxed_body(); if let Ok(value) = HeaderValue::try_from(request_id.as_str()) { response.headers_mut().insert(REQUEST_ID_HEADER, value); } Ok(response) } fn header(request: &ServiceRequest) -> Option<&str> { request .headers() .get(&REQUEST_ID_HEADER) .and_then(|value| value.to_str().ok()) }