scufflecloud_ext/
http_ext.rs

1use std::sync::Arc;
2
3use crate::OptionExt;
4
5pub trait RequestExt {
6    fn extensions(&self) -> &http::Extensions;
7
8    fn global<G: Send + Sync + 'static>(&self) -> Result<Arc<G>, tonic::Status> {
9        self.extensions()
10            .get::<Arc<G>>()
11            .map(Arc::clone)
12            .into_tonic_internal_err("missing global extension")
13    }
14
15    fn origin(&self) -> Option<url::Url>;
16
17    fn user_agent(&self) -> Option<&str>;
18}
19
20impl<T> RequestExt for tonic::Request<T> {
21    fn extensions(&self) -> &http::Extensions {
22        self.extensions()
23    }
24
25    fn origin(&self) -> Option<url::Url> {
26        self.metadata().get("origin")?.to_str().ok()?.parse().ok()
27    }
28
29    fn user_agent(&self) -> Option<&str> {
30        self.metadata().get("user-agent")?.to_str().ok()
31    }
32}
33
34impl RequestExt for tonic::Extensions {
35    fn extensions(&self) -> &http::Extensions {
36        self
37    }
38
39    fn origin(&self) -> Option<url::Url> {
40        None
41    }
42
43    fn user_agent(&self) -> Option<&str> {
44        None
45    }
46}
47
48impl<T> RequestExt for http::Request<T> {
49    fn extensions(&self) -> &http::Extensions {
50        self.extensions()
51    }
52
53    fn origin(&self) -> Option<url::Url> {
54        self.headers().get("origin")?.to_str().ok()?.parse().ok()
55    }
56
57    fn user_agent(&self) -> Option<&str> {
58        self.headers().get("user-agent")?.to_str().ok()
59    }
60}