use crate::dyn_mod::*;
use crate::salvo::{self, handler, http::HeaderValue};
use std::sync::Arc;
use sulid::SulidGenerator;
pub const HEADER_REQUEST_ID: &'static str = "x-request-id";
pub struct RequestIdHoop {
sulid: Arc<SulidGenerator>,
}
#[handler]
impl RequestIdHoop {
pub fn new(worker_id: u16) -> Self {
Self {
sulid: Arc::new(SulidGenerator::v2_new(worker_id)),
}
}
async fn handle(
&self,
request: &mut Request,
depot: &mut Depot,
response: &mut Response,
ctrl: &mut FlowCtrl,
) {
let mut is_gen = false;
let request_id = match request.headers().get(HEADER_REQUEST_ID) {
Some(v) => v.to_str().map(|s| s.to_owned()).unwrap_or_else(|_| {
is_gen = true;
self.sulid.generate().to_string()
}),
None => {
is_gen = true;
self.sulid.generate().to_string()
}
};
if is_gen {
let header_request_id = HeaderValue::from_str(request_id.as_str()).unwrap();
request
.add_header(HEADER_REQUEST_ID, header_request_id.clone(), true)
.ok();
response
.add_header(HEADER_REQUEST_ID, header_request_id, true)
.ok();
}
depot.insert(HEADER_REQUEST_ID, request_id.clone());
ctrl.call_next(request, depot, response).await;
}
}