use std::sync::{atomic::Ordering, Arc};
use std::time::Instant;
use axum::{
body::Body,
extract::State,
http::{header, HeaderMap, HeaderName, HeaderValue},
middleware::Next,
response::Response,
};
use crate::Core;
pub(crate) async fn add_core_response_headers(
State(core): State<Arc<Core>>,
mut req: axum::http::Request<Body>,
next: Next,
) -> Response {
let request_id = core.next_request.fetch_add(1, Ordering::Relaxed) + 1;
req.extensions_mut()
.insert(crate::pipeline::RequestId(request_id));
let start = Instant::now();
let mut response = next.run(req).await;
stamp_core_response_headers(
request_id,
start.elapsed().as_micros(),
response.headers_mut(),
);
response
}
pub(crate) fn stamp_core_response_headers(
request_id: u64,
elapsed_us: u128,
headers: &mut HeaderMap,
) {
headers.insert(
HeaderName::from_static("x-request-id"),
HeaderValue::from_str(&request_id.to_string())
.unwrap_or_else(|_| HeaderValue::from_static("0")),
);
headers.insert(
HeaderName::from_static("x-elapsed-us"),
HeaderValue::from_str(&elapsed_us.to_string())
.unwrap_or_else(|_| HeaderValue::from_static("0")),
);
headers.insert(header::VARY, HeaderValue::from_static("Authorization"));
headers.insert(
HeaderName::from_static("x-content-type-options"),
HeaderValue::from_static("nosniff"),
);
}