1pub(crate) mod compression_error;
3mod entry;
4mod entry_name;
5mod field_section;
6mod header_name;
7pub(crate) mod header_observer;
8mod header_value;
9mod header_values;
10#[cfg(feature = "unstable")]
11pub mod hpack;
12#[cfg(not(feature = "unstable"))]
13pub(crate) mod hpack;
14pub(crate) mod huffman;
15mod integer_prefix;
16mod known_header_name;
17pub(in crate::headers) mod recent_pairs;
18mod static_hit;
19mod unknown_header_name;
20
21#[cfg(feature = "unstable")]
22pub mod qpack;
23
24#[cfg(not(feature = "unstable"))]
25pub(crate) mod qpack;
26
27use crate::headers::entry::{OccupiedEntryInner, VacantEntryInner};
28pub use entry::{Entry, OccupiedEntry, VacantEntry};
29use hashbrown::{
30 HashMap,
31 hash_map::{self, Entry as HashbrownEntry},
32};
33pub use header_name::HeaderName;
34use header_name::HeaderNameInner;
35pub use header_value::HeaderValue;
36pub use header_values::HeaderValues;
37pub use known_header_name::KnownHeaderName;
38use std::{
39 collections::{
40 BTreeMap,
41 btree_map::{self, Entry as BTreeEntry},
42 },
43 fmt::{self, Debug, Display, Formatter},
44};
45use unknown_header_name::UnknownHeaderName;
46
47#[derive(Debug, Clone, PartialEq, Eq, Default)]
49#[must_use]
50pub struct Headers {
51 pub(crate) known: BTreeMap<KnownHeaderName, HeaderValues>,
52 pub(crate) unknown: HashMap<UnknownHeaderName<'static>, HeaderValues>,
53}
54
55pub const SERVER_HEADER: HeaderValue =
57 HeaderValue::const_new(concat!("trillium-http/", env!("CARGO_PKG_VERSION")));
58
59#[cfg(feature = "serde")]
60impl serde::Serialize for Headers {
61 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62 where
63 S: serde::Serializer,
64 {
65 use serde::ser::SerializeMap;
66 let mut map = serializer.serialize_map(Some(self.len()))?;
67 for (key, values) in self {
68 map.serialize_entry(&key, values)?;
69 }
70 map.end()
71 }
72}
73
74impl Display for Headers {
75 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
76 let mut data = self.iter().collect::<Vec<_>>();
79 data.sort_by(|(a, _), (b, _)| a.cmp(b));
80 for (n, v) in data {
81 for v in v {
82 f.write_fmt(format_args!("{n}: {v}\r\n"))?;
83 }
84 }
85 Ok(())
86 }
87}
88
89#[cfg(feature = "parse")]
90impl Headers {
91 #[doc(hidden)]
92 pub fn extend_parse(&mut self, bytes: &[u8]) -> Result<usize, crate::Error> {
93 use memchr::memmem::Finder;
94
95 let mut new_header_count = 0;
96 let mut last_line = 0;
97 for newline in Finder::new(b"\r\n").find_iter(bytes) {
98 if newline == last_line {
99 continue;
100 }
101
102 let line = &bytes[last_line..newline];
103 let colon = memchr::memchr(b':', line).ok_or(crate::Error::InvalidHead)?;
104
105 let header_name = HeaderName::parse(&line[..colon])?.to_owned();
106
107 let token_end = last_line + colon;
108
109 let mut value_start = token_end + 1;
110
111 while bytes
112 .get(value_start)
113 .is_some_and(|b| matches!(b, b'\t' | b' '))
114 {
115 value_start += 1;
116 }
117
118 let header_value = HeaderValue::parse(bytes[value_start..newline].trim_ascii_end());
119 self.append(header_name, header_value);
120 new_header_count += 1;
121 last_line = newline + 2;
122 }
123 Ok(new_header_count)
124 }
125
126 #[doc(hidden)]
127 pub fn parse(bytes: &[u8]) -> Result<Self, crate::Error> {
128 let mut headers = Headers::new();
129 headers.extend_parse(bytes)?;
130 Ok(headers)
131 }
132}
133
134impl Headers {
135 pub fn new() -> Self {
137 Self::default()
138 }
139
140 pub fn iter(&self) -> Iter<'_> {
144 self.into()
145 }
146
147 pub fn is_empty(&self) -> bool {
149 self.known.is_empty() && self.unknown.is_empty()
150 }
151
152 pub fn len(&self) -> usize {
155 self.known.len() + self.unknown.len()
156 }
157
158 pub fn append(
165 &mut self,
166 name: impl Into<HeaderName<'static>>,
167 values: impl Into<HeaderValues>,
168 ) -> &mut HeaderValues {
169 self.entry(name).append(values)
170 }
171
172 pub fn append_all(&mut self, other: Headers) {
175 for (name, value) in other.known {
176 match self.known.entry(name) {
177 BTreeEntry::Occupied(mut entry) => {
178 entry.get_mut().extend(value);
179 }
180 BTreeEntry::Vacant(entry) => {
181 entry.insert(value);
182 }
183 }
184 }
185
186 for (name, value) in other.unknown {
187 match self.unknown.entry(name) {
188 HashbrownEntry::Occupied(mut entry) => {
189 entry.get_mut().extend(value);
190 }
191 HashbrownEntry::Vacant(entry) => {
192 entry.insert(value);
193 }
194 }
195 }
196 }
197
198 pub fn insert_all(&mut self, other: Headers) {
200 for (name, value) in other.known {
201 self.known.insert(name, value);
202 }
203
204 for (name, value) in other.unknown {
205 self.unknown.insert(name, value);
206 }
207 }
208
209 pub fn insert(
213 &mut self,
214 name: impl Into<HeaderName<'static>>,
215 values: impl Into<HeaderValues>,
216 ) -> &mut Self {
217 self.entry(name).insert(values);
218 self
219 }
220
221 pub fn try_insert(
226 &mut self,
227 name: impl Into<HeaderName<'static>>,
228 values: impl Into<HeaderValues>,
229 ) -> &mut Self {
230 self.entry(name).or_insert(values);
231 self
232 }
233
234 pub fn try_insert_with<V>(
239 &mut self,
240 name: impl Into<HeaderName<'static>>,
241 values: impl FnOnce() -> V,
242 ) -> &mut HeaderValues
243 where
244 V: Into<HeaderValues>,
245 {
246 self.entry(name).or_insert_with(values)
247 }
248
249 pub fn entry(&mut self, name: impl Into<HeaderName<'static>>) -> Entry<'_> {
253 match name.into().0 {
254 HeaderNameInner::KnownHeader(known) => match self.known.entry(known) {
255 BTreeEntry::Vacant(vacant) => {
256 Entry::Vacant(VacantEntry(VacantEntryInner::Known(vacant)))
257 }
258 BTreeEntry::Occupied(occupied) => {
259 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Known(occupied)))
260 }
261 },
262
263 HeaderNameInner::UnknownHeader(unknown) => match self.unknown.entry(unknown) {
264 HashbrownEntry::Occupied(occupied) => {
265 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Unknown(occupied)))
266 }
267
268 HashbrownEntry::Vacant(vacant) => {
269 Entry::Vacant(VacantEntry(VacantEntryInner::Unknown(vacant)))
270 }
271 },
272 }
273 }
274
275 pub fn get_str<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&str> {
281 self.get_values(name).and_then(HeaderValues::as_str)
282 }
283
284 pub fn get<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValue> {
288 self.get_values(name).and_then(HeaderValues::one)
289 }
290
291 pub fn remove<'a>(&mut self, name: impl Into<HeaderName<'a>>) -> Option<HeaderValues> {
294 match name.into().0 {
295 HeaderNameInner::KnownHeader(known) => self.known.remove(&known),
296 HeaderNameInner::UnknownHeader(unknown) => self.unknown.remove(&&unknown),
297 }
298 }
299
300 pub fn get_values<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValues> {
304 match name.into().0 {
305 HeaderNameInner::KnownHeader(known) => self.known.get(&known),
306 HeaderNameInner::UnknownHeader(unknown) => self.unknown.get(&&unknown),
307 }
308 }
309
310 pub fn has_header<'a>(&self, name: impl Into<HeaderName<'a>>) -> bool {
315 match name.into().0 {
316 HeaderNameInner::KnownHeader(known) => self.known.contains_key(&known),
317 HeaderNameInner::UnknownHeader(unknown) => self.unknown.contains_key(&unknown),
318 }
319 }
320
321 pub fn eq_ignore_ascii_case<'a>(
326 &'a self,
327 name: impl Into<HeaderName<'a>>,
328 needle: &str,
329 ) -> bool {
330 self.get_str(name)
331 .is_some_and(|v| v.eq_ignore_ascii_case(needle))
332 }
333
334 pub fn with_inserted_header(
336 mut self,
337 name: impl Into<HeaderName<'static>>,
338 values: impl Into<HeaderValues>,
339 ) -> Self {
340 self.insert(name, values);
341 self
342 }
343
344 pub fn with_appended_header(
346 mut self,
347 name: impl Into<HeaderName<'static>>,
348 values: impl Into<HeaderValues>,
349 ) -> Self {
350 self.append(name, values);
351 self
352 }
353
354 pub fn without_header<'a>(mut self, name: impl Into<HeaderName<'a>>) -> Self {
356 self.remove(name);
357 self
358 }
359
360 pub fn without_headers<'a, I, H>(mut self, names: I) -> Self
362 where
363 I: IntoIterator<Item = H>,
364 H: Into<HeaderName<'a>>,
365 {
366 self.remove_all(names);
367 self
368 }
369
370 pub fn remove_all<'a, I, H>(&mut self, names: I)
372 where
373 I: IntoIterator<Item = H>,
374 H: Into<HeaderName<'a>>,
375 {
376 for name in names {
377 self.remove(name);
378 }
379 }
380}
381
382impl<HN, HV> Extend<(HN, HV)> for Headers
383where
384 HN: Into<HeaderName<'static>>,
385 HV: Into<HeaderValues>,
386{
387 fn extend<T: IntoIterator<Item = (HN, HV)>>(&mut self, iter: T) {
388 for (name, values) in iter {
389 self.append(name, values);
390 }
391 }
392}
393
394impl<HN, HV> FromIterator<(HN, HV)> for Headers
395where
396 HN: Into<HeaderName<'static>>,
397 HV: Into<HeaderValues>,
398{
399 fn from_iter<T: IntoIterator<Item = (HN, HV)>>(iter: T) -> Self {
400 let iter = iter.into_iter();
401 let mut headers = Self::new();
402 for (name, values) in iter {
403 headers.append(name, values);
404 }
405
406 headers
407 }
408}
409
410impl<'a> IntoIterator for &'a Headers {
411 type IntoIter = Iter<'a>;
412 type Item = (HeaderName<'a>, &'a HeaderValues);
413
414 fn into_iter(self) -> Self::IntoIter {
415 self.into()
416 }
417}
418
419#[derive(Debug)]
421pub struct IntoIter {
422 known: btree_map::IntoIter<KnownHeaderName, HeaderValues>,
423 unknown: hash_map::IntoIter<UnknownHeaderName<'static>, HeaderValues>,
424}
425
426impl Iterator for IntoIter {
427 type Item = (HeaderName<'static>, HeaderValues);
428
429 fn next(&mut self) -> Option<Self::Item> {
430 let IntoIter { known, unknown } = self;
431 known
432 .next()
433 .map(|(k, v)| (HeaderName::from(k), v))
434 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(k), v)))
435 }
436}
437
438impl From<Headers> for IntoIter {
439 fn from(value: Headers) -> Self {
440 Self {
441 known: value.known.into_iter(),
442 unknown: value.unknown.into_iter(),
443 }
444 }
445}
446
447#[derive(Debug)]
449pub struct Iter<'a> {
450 known: btree_map::Iter<'a, KnownHeaderName, HeaderValues>,
451 unknown: hash_map::Iter<'a, UnknownHeaderName<'static>, HeaderValues>,
452}
453
454impl<'a> From<&'a Headers> for Iter<'a> {
455 fn from(value: &'a Headers) -> Self {
456 Iter {
457 known: value.known.iter(),
458 unknown: value.unknown.iter(),
459 }
460 }
461}
462
463impl<'a> Iterator for Iter<'a> {
464 type Item = (HeaderName<'a>, &'a HeaderValues);
465
466 fn next(&mut self) -> Option<Self::Item> {
467 let Iter { known, unknown } = self;
468 known
469 .next()
470 .map(|(k, v)| (HeaderName::from(*k), v))
471 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(&**k), v)))
472 }
473}
474
475impl IntoIterator for Headers {
476 type IntoIter = IntoIter;
477 type Item = (HeaderName<'static>, HeaderValues);
478
479 fn into_iter(self) -> Self::IntoIter {
480 self.into()
481 }
482}