stream_httparse/
headers.rs

1use crate::{
2    header::{HeaderKey, HeaderValue},
3    Header,
4};
5
6/// A collection of Headers
7#[derive(Debug, PartialEq, Clone)]
8pub struct Headers<'a> {
9    headers: Vec<Header<'a>>,
10    max_value_length: usize,
11}
12
13impl<'a> Headers<'a> {
14    /// Creates a new Headers-Instance, for performance reasons
15    /// it is recommended to use the `with_capacity` method
16    /// as that would avoid frequent reallocations
17    pub fn new() -> Self {
18        Self {
19            headers: Vec::new(),
20            max_value_length: 0,
21        }
22    }
23
24    /// Creates the Headers-Object with the given Capacity
25    /// prereserved for future Headers.
26    /// This should be used when you already kind of know
27    /// how many Headers this will hold, as it will avoid
28    /// extra allocations in the future
29    pub fn with_capacity(cap: usize) -> Self {
30        Self {
31            headers: Vec::with_capacity(cap),
32            max_value_length: 0,
33        }
34    }
35
36    /// Sets the Value of the of the Header for the given Key to
37    /// the given Value
38    ///
39    /// ## Behaviour
40    /// Checks if the Key is already present in the Collection and
41    /// removes it if that is the case.
42    /// Then adds the new Header to the End of the Collection
43    pub fn set<'b, K, V>(&mut self, key: K, value: V)
44    where
45        'b: 'a,
46        K: Into<HeaderKey<'a>>,
47        V: Into<HeaderValue<'a>>,
48    {
49        let final_key = key.into();
50        if let Some(index) = self.find(&final_key) {
51            self.headers.remove(index);
52        }
53
54        let n_value: HeaderValue = value.into();
55        let n_value_length = n_value.length();
56        if n_value_length > self.max_value_length {
57            self.max_value_length = n_value_length;
58        }
59
60        self.headers.push(Header {
61            key: final_key,
62            value: n_value,
63        });
64    }
65
66    /// Appends the given Key-Value Pair to the end of the
67    /// Collection, without checking if the Key is already
68    /// present in the Collection
69    pub fn append<K, V>(&mut self, key: K, value: V)
70    where
71        K: Into<HeaderKey<'a>>,
72        V: Into<HeaderValue<'a>>,
73    {
74        let n_value: HeaderValue = value.into();
75        let n_value_length = n_value.length();
76        if n_value_length > self.max_value_length {
77            self.max_value_length = n_value_length;
78        }
79
80        self.headers.push(Header {
81            key: key.into(),
82            value: n_value,
83        })
84    }
85
86    fn find(&self, key: &HeaderKey<'a>) -> Option<usize> {
87        for (index, pair) in self.headers.iter().enumerate() {
88            if &pair.key == key {
89                return Some(index);
90            }
91        }
92        None
93    }
94
95    /// Removes the first Header, that matches the given
96    /// Key, from the Collection
97    pub fn remove<K>(&mut self, key: K)
98    where
99        K: Into<HeaderKey<'a>>,
100    {
101        if let Some(index) = self.find(&key.into()) {
102            self.headers.remove(index);
103        }
104    }
105
106    /// Searches the Collection for a Header that matches
107    /// the given Key
108    ///
109    /// Returns:
110    /// * None: if no Header matches the Key
111    /// * A Reference to the underlying Header-Value that
112    /// belongs to the Key
113    pub fn get<K>(&self, key: K) -> Option<&HeaderValue<'a>>
114    where
115        K: Into<HeaderKey<'a>>,
116    {
117        self.find(&key.into())
118            .map(|index| &self.headers.get(index).unwrap().value)
119    }
120
121    /// Serializes the Collection of Headers into the
122    /// given Buffer by append to it
123    pub fn serialize(&self, buf: &mut Vec<u8>) {
124        for pair in self.headers.iter() {
125            pair.serialize(buf);
126        }
127    }
128
129    /// Returns the Size in bytes of the biggest Value as text.
130    ///
131    /// This means that all the Header-Values in this collection
132    /// can fit in a buffer of this size.
133    pub fn get_max_value_size(&self) -> usize {
134        self.max_value_length
135    }
136
137    /// Returns the Number of Headers in this collection
138    pub fn get_header_count(&self) -> usize {
139        self.headers.len()
140    }
141
142    /// Clones all the assosicated Data to produce a new and
143    /// independant Header-Collection
144    pub fn to_owned<'refed, 'owned>(&'refed self) -> Headers<'owned> {
145        let mut n_headers = Vec::with_capacity(self.headers.len());
146
147        for tmp in self.headers.iter() {
148            n_headers.push(tmp.to_owned());
149        }
150
151        Headers {
152            headers: n_headers,
153            max_value_length: self.max_value_length,
154        }
155    }
156}
157
158impl<'a> Default for Headers<'a> {
159    fn default() -> Self {
160        Self::new()
161    }
162}
163
164#[cfg(test)]
165mod tests {
166    use super::*;
167
168    #[test]
169    fn headers_add_new() {
170        let mut headers = Headers::new();
171        headers.set("test-key", "test-value");
172
173        assert_eq!(
174            vec![Header {
175                key: HeaderKey::StrRef("test-key"),
176                value: HeaderValue::StrRef("test-value")
177            }],
178            headers.headers
179        );
180    }
181    #[test]
182    fn headers_add_already_exists() {
183        let mut headers = Headers::new();
184        headers.set("test-key", "test-value");
185
186        assert_eq!(
187            vec![Header {
188                key: HeaderKey::StrRef("test-key"),
189                value: HeaderValue::StrRef("test-value")
190            }],
191            headers.headers
192        );
193
194        headers.set("test-key", "other value");
195        assert_eq!(
196            vec![Header {
197                key: HeaderKey::StrRef("test-key"),
198                value: HeaderValue::StrRef("other value")
199            }],
200            headers.headers
201        );
202    }
203
204    #[test]
205    fn headers_remove_existing() {
206        let mut headers = Headers::new();
207        headers.set("test-key", "test-value");
208
209        assert_eq!(
210            vec![Header {
211                key: HeaderKey::StrRef("test-key"),
212                value: HeaderValue::StrRef("test-value")
213            }],
214            headers.headers
215        );
216
217        headers.remove("test-key");
218        assert_eq!(Vec::<Header>::new(), headers.headers);
219    }
220    #[test]
221    fn headers_remove_non_existing() {
222        let mut headers = Headers::new();
223        headers.set("test-key", "test-value");
224
225        assert_eq!(
226            vec![Header {
227                key: HeaderKey::StrRef("test-key"),
228                value: HeaderValue::StrRef("test-value")
229            }],
230            headers.headers
231        );
232
233        headers.remove("other-key");
234        assert_eq!(
235            vec![Header {
236                key: HeaderKey::StrRef("test-key"),
237                value: HeaderValue::StrRef("test-value")
238            }],
239            headers.headers
240        );
241    }
242
243    #[test]
244    fn headers_get_existing() {
245        let mut headers = Headers::new();
246        headers.set("test-key", "test-value");
247
248        assert_eq!(
249            vec![Header {
250                key: HeaderKey::StrRef("test-key"),
251                value: HeaderValue::StrRef("test-value")
252            }],
253            headers.headers
254        );
255
256        assert_eq!(
257            Some(&HeaderValue::StrRef("test-value")),
258            headers.get("test-key")
259        );
260    }
261    #[test]
262    fn headers_get_not_existing() {
263        let mut headers = Headers::new();
264        headers.set("test-key", "test-value");
265
266        assert_eq!(
267            vec![Header {
268                key: HeaderKey::StrRef("test-key"),
269                value: HeaderValue::StrRef("test-value")
270            }],
271            headers.headers
272        );
273
274        assert_eq!(None, headers.get("other-key"));
275    }
276
277    #[test]
278    fn headers_serialize() {
279        let mut headers = Headers::new();
280        headers.set("test-key", "test-value");
281
282        assert_eq!(
283            vec![Header {
284                key: HeaderKey::StrRef("test-key"),
285                value: HeaderValue::StrRef("test-value")
286            }],
287            headers.headers
288        );
289
290        let result = "test-key: test-value\r\n".as_bytes();
291        let mut tmp: Vec<u8> = Vec::new();
292        headers.serialize(&mut tmp);
293        assert_eq!(result, &tmp);
294    }
295}