use tide::{Middleware, Next, Request};
#[cfg(feature = "test")]
use uuid::Uuid;
use super::extension_types::RequestId;
#[derive(Debug, Default, Clone)]
pub struct RequestIdMiddleware {
_priv: (),
}
impl RequestIdMiddleware {
#[must_use]
pub fn new() -> Self {
Self { _priv: () }
}
async fn handle<'a, State: Clone + Send + Sync + 'static>(
&'a self,
mut req: Request<State>,
next: Next<'a, State>,
) -> tide::Result {
if req.ext::<RequestId>().is_some() {
return Ok(next.run(req).await);
}
let request_id: RequestId;
#[cfg(not(feature = "test"))]
if let Some(header) = req.header("X-Request-Id") {
request_id = match header.last().as_str().parse() {
Ok(id) => id,
Err(e) => {
log::warn!("Invalid X-Request-Id: \"{}\" - Error: {}", header, e);
RequestId::new()
}
};
} else {
request_id = RequestId::new();
}
#[cfg(feature = "test")]
{
request_id = Uuid::nil().into()
}
req.set_ext(request_id.clone());
let mut res = next.run(req).await;
res.insert_header("X-Request-Id", request_id.as_str());
Ok(res)
}
}
#[tide::utils::async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for RequestIdMiddleware {
async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> tide::Result {
self.handle(req, next).await
}
}