Skip to main content

minco_http/
request_id.rs

1use http::HeaderMap;
2use uuid::Uuid;
3
4use crate::REQUEST_ID_HEADER;
5
6/// Maximum accepted byte length of an untrusted correlation ID.
7pub const MAX_REQUEST_ID_BYTES: usize = 128;
8
9/// Return whether a request ID uses Minco's bounded correlation-safe grammar.
10#[must_use]
11pub fn is_valid_request_id(value: &str) -> bool {
12    !value.is_empty()
13        && value.len() <= MAX_REQUEST_ID_BYTES
14        && value
15            .bytes()
16            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_' | b'.' | b':'))
17}
18
19/// Preserve a safe request ID or replace untrusted input with `UUIDv7`.
20#[must_use]
21pub fn safe_request_id(value: Option<&str>) -> String {
22    value
23        .filter(|value| is_valid_request_id(value))
24        .map_or_else(|| Uuid::now_v7().to_string(), str::to_owned)
25}
26
27/// Read a safe correlation ID from request headers.
28#[must_use]
29pub fn request_id_from_headers(headers: &HeaderMap) -> String {
30    safe_request_id(
31        headers
32            .get(&REQUEST_ID_HEADER)
33            .and_then(|value| value.to_str().ok()),
34    )
35}