rama_http_headers/forwarded/
std.rs1use std::ops::{Deref, DerefMut};
2
3use rama_http_types::{HeaderName, HeaderValue, header::FORWARDED};
4use rama_net::forwarded::ForwardedElement;
5
6use crate::{Error, Header};
7
8use super::ForwardHeader;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Forwarded(rama_net::forwarded::Forwarded);
13
14impl Deref for Forwarded {
15 type Target = rama_net::forwarded::Forwarded;
16
17 fn deref(&self) -> &Self::Target {
18 &self.0
19 }
20}
21
22impl DerefMut for Forwarded {
23 fn deref_mut(&mut self) -> &mut Self::Target {
24 &mut self.0
25 }
26}
27
28impl Forwarded {
29 #[inline]
30 pub fn into_inner(self) -> rama_net::forwarded::Forwarded {
34 self.0
35 }
36}
37
38impl From<rama_net::forwarded::Forwarded> for Forwarded {
39 fn from(value: rama_net::forwarded::Forwarded) -> Self {
40 Self(value)
41 }
42}
43
44impl From<Forwarded> for rama_net::forwarded::Forwarded {
45 fn from(value: Forwarded) -> Self {
46 value.0
47 }
48}
49
50impl Header for Forwarded {
51 fn name() -> &'static HeaderName {
52 &FORWARDED
53 }
54
55 fn decode<'i, I>(values: &mut I) -> Result<Self, Error>
56 where
57 Self: Sized,
58 I: Iterator<Item = &'i HeaderValue>,
59 {
60 let first_header = values.next().ok_or_else(Error::invalid)?;
61
62 let mut forwarded: rama_net::forwarded::Forwarded = match first_header.as_bytes().try_into()
63 {
64 Ok(f) => f,
65 Err(err) => {
66 tracing::trace!(err = %err, "failed to turn header into Forwarded extension");
67 return Err(Error::invalid());
68 }
69 };
70
71 for header in values {
72 let other: rama_net::forwarded::Forwarded = match header.as_bytes().try_into() {
73 Ok(f) => f,
74 Err(err) => {
75 tracing::trace!(err = %err, "failed to turn header into Forwarded extension");
76 return Err(Error::invalid());
77 }
78 };
79 forwarded.extend(other);
80 }
81
82 Ok(Self(forwarded))
83 }
84
85 fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
86 let s = self.0.to_string();
87
88 let value = HeaderValue::from_str(&s)
89 .expect("Forwarded extension should always result in a valid header value");
90
91 values.extend(std::iter::once(value));
92 }
93}
94
95impl IntoIterator for Forwarded {
96 type Item = <rama_net::forwarded::Forwarded as IntoIterator>::Item;
97 type IntoIter = <rama_net::forwarded::Forwarded as IntoIterator>::IntoIter;
98
99 #[inline]
100 fn into_iter(self) -> Self::IntoIter {
101 self.0.into_iter()
102 }
103}
104
105impl ForwardHeader for Forwarded {
106 fn try_from_forwarded<'a, I>(input: I) -> Option<Self>
107 where
108 I: IntoIterator<Item = &'a ForwardedElement>,
109 {
110 let mut it = input.into_iter();
111 let mut forwarded = rama_net::forwarded::Forwarded::new(it.next()?.clone());
112 forwarded.extend(it.cloned());
113 Some(Self(forwarded))
114 }
115}