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}