Skip to main content

rs_zero/rpc/
interceptor.rs

1use tonic::{Request, Status, service::Interceptor};
2use uuid::Uuid;
3
4/// Metadata key propagated by rs-zero RPC clients.
5pub const REQUEST_ID_METADATA: &str = "x-request-id";
6
7/// Builds an interceptor that adds a request id when missing.
8pub fn request_id_interceptor() -> impl Interceptor {
9    |mut request: Request<()>| -> Result<Request<()>, Status> {
10        if !request.metadata().contains_key(REQUEST_ID_METADATA) {
11            let request_id = Uuid::new_v4().to_string();
12            let value = request_id
13                .parse()
14                .map_err(|_| Status::internal("invalid request id metadata"))?;
15            request.metadata_mut().insert(REQUEST_ID_METADATA, value);
16        }
17
18        Ok(request)
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use super::{REQUEST_ID_METADATA, request_id_interceptor};
25    use tonic::{Request, service::Interceptor};
26
27    #[test]
28    fn interceptor_sets_request_id() {
29        let mut interceptor = request_id_interceptor();
30        let request = interceptor.call(Request::new(())).expect("request");
31
32        assert!(request.metadata().contains_key(REQUEST_ID_METADATA));
33    }
34}