1pub(crate) mod compression_error;
3pub(crate) mod date;
4mod entry;
5mod entry_name;
6mod field_section;
7mod header_name;
8pub(crate) mod header_observer;
9mod header_value;
10mod header_values;
11#[cfg(feature = "unstable")]
12pub mod hpack;
13#[cfg(not(feature = "unstable"))]
14pub(crate) mod hpack;
15pub(crate) mod huffman;
16mod integer_prefix;
17mod known_header_name;
18pub(in crate::headers) mod recent_pairs;
19mod static_hit;
20mod unknown_header_name;
21
22#[cfg(feature = "unstable")]
23pub mod qpack;
24
25#[cfg(not(feature = "unstable"))]
26pub(crate) mod qpack;
27
28use crate::headers::entry::{OccupiedEntryInner, VacantEntryInner};
29pub use entry::{Entry, OccupiedEntry, VacantEntry};
30use hashbrown::{
31 HashMap,
32 hash_map::{self, Entry as HashbrownEntry},
33};
34pub use header_name::HeaderName;
35use header_name::HeaderNameInner;
36pub use header_value::HeaderValue;
37pub use header_values::HeaderValues;
38pub use known_header_name::KnownHeaderName;
39use std::{
40 collections::{
41 BTreeMap,
42 btree_map::{self, Entry as BTreeEntry},
43 },
44 fmt::{self, Debug, Display, Formatter},
45};
46use unknown_header_name::UnknownHeaderName;
47
48#[derive(Debug, Clone, PartialEq, Eq, Default)]
50#[must_use]
51pub struct Headers {
52 pub(crate) known: BTreeMap<KnownHeaderName, HeaderValues>,
53 pub(crate) unknown: HashMap<UnknownHeaderName<'static>, HeaderValues>,
54}
55
56pub const SERVER_HEADER: HeaderValue =
58 HeaderValue::const_new(concat!("trillium-http/", env!("CARGO_PKG_VERSION")));
59
60#[cfg(feature = "serde")]
61impl serde::Serialize for Headers {
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: serde::Serializer,
65 {
66 use serde::ser::SerializeMap;
67 let mut map = serializer.serialize_map(Some(self.len()))?;
68 for (key, values) in self {
69 map.serialize_entry(&key, values)?;
70 }
71 map.end()
72 }
73}
74
75impl Display for Headers {
76 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
77 let mut data = self.iter().collect::<Vec<_>>();
80 data.sort_by(|(a, _), (b, _)| a.cmp(b));
81 for (n, v) in data {
82 for v in v {
83 f.write_fmt(format_args!("{n}: {v}\r\n"))?;
84 }
85 }
86 Ok(())
87 }
88}
89
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
104 let colon = memchr::memchr(b':', line).ok_or(crate::Error::InvalidHeaderName)?;
110 let name = HeaderName::parse(&line[..colon])?;
111 if !name.is_valid() {
112 return Err(crate::Error::InvalidHeaderName);
113 }
114
115 let mut value_start = colon + 1;
116 while line
117 .get(value_start)
118 .is_some_and(|b| matches!(b, b'\t' | b' '))
119 {
120 value_start += 1;
121 }
122 let value_bytes = line[value_start..].trim_ascii_end();
123 if !value_bytes.iter().all(|&b| b >= 0x20 || b == b'\t') {
125 return Err(crate::Error::InvalidHeaderValue(name.to_owned()));
126 }
127
128 self.append(name.to_owned(), HeaderValue::parse(value_bytes));
129 new_header_count += 1;
130 last_line = newline + 2;
131 }
132 Ok(new_header_count)
133 }
134
135 #[doc(hidden)]
136 pub fn parse(bytes: &[u8]) -> Result<Self, crate::Error> {
137 let mut headers = Headers::new();
138 headers.extend_parse(bytes)?;
139 Ok(headers)
140 }
141}
142
143impl Headers {
144 pub fn new() -> Self {
146 Self::default()
147 }
148
149 pub fn iter(&self) -> Iter<'_> {
153 self.into()
154 }
155
156 pub fn is_empty(&self) -> bool {
158 self.known.is_empty() && self.unknown.is_empty()
159 }
160
161 pub fn len(&self) -> usize {
164 self.known.len() + self.unknown.len()
165 }
166
167 pub fn append(
174 &mut self,
175 name: impl Into<HeaderName<'static>>,
176 values: impl Into<HeaderValues>,
177 ) -> &mut HeaderValues {
178 self.entry(name).append(values)
179 }
180
181 pub fn append_all(&mut self, other: Headers) {
184 for (name, value) in other.known {
185 match self.known.entry(name) {
186 BTreeEntry::Occupied(mut entry) => {
187 entry.get_mut().extend(value);
188 }
189 BTreeEntry::Vacant(entry) => {
190 entry.insert(value);
191 }
192 }
193 }
194
195 for (name, value) in other.unknown {
196 match self.unknown.entry(name) {
197 HashbrownEntry::Occupied(mut entry) => {
198 entry.get_mut().extend(value);
199 }
200 HashbrownEntry::Vacant(entry) => {
201 entry.insert(value);
202 }
203 }
204 }
205 }
206
207 pub fn insert_all(&mut self, other: Headers) {
209 for (name, value) in other.known {
210 self.known.insert(name, value);
211 }
212
213 for (name, value) in other.unknown {
214 self.unknown.insert(name, value);
215 }
216 }
217
218 pub fn insert(
222 &mut self,
223 name: impl Into<HeaderName<'static>>,
224 values: impl Into<HeaderValues>,
225 ) -> &mut Self {
226 self.entry(name).insert(values);
227 self
228 }
229
230 pub fn try_insert(
235 &mut self,
236 name: impl Into<HeaderName<'static>>,
237 values: impl Into<HeaderValues>,
238 ) -> &mut Self {
239 self.entry(name).or_insert(values);
240 self
241 }
242
243 pub fn try_insert_with<V>(
248 &mut self,
249 name: impl Into<HeaderName<'static>>,
250 values: impl FnOnce() -> V,
251 ) -> &mut HeaderValues
252 where
253 V: Into<HeaderValues>,
254 {
255 self.entry(name).or_insert_with(values)
256 }
257
258 pub fn entry(&mut self, name: impl Into<HeaderName<'static>>) -> Entry<'_> {
262 match name.into().0 {
263 HeaderNameInner::KnownHeader(known) => match self.known.entry(known) {
264 BTreeEntry::Vacant(vacant) => {
265 Entry::Vacant(VacantEntry(VacantEntryInner::Known(vacant)))
266 }
267 BTreeEntry::Occupied(occupied) => {
268 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Known(occupied)))
269 }
270 },
271
272 HeaderNameInner::UnknownHeader(unknown) => match self.unknown.entry(unknown) {
273 HashbrownEntry::Occupied(occupied) => {
274 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Unknown(occupied)))
275 }
276
277 HashbrownEntry::Vacant(vacant) => {
278 Entry::Vacant(VacantEntry(VacantEntryInner::Unknown(vacant)))
279 }
280 },
281 }
282 }
283
284 pub fn get_str<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&str> {
290 self.get_values(name).and_then(HeaderValues::as_str)
291 }
292
293 pub fn content_length(&self) -> Option<u64> {
298 self.get_values(KnownHeaderName::ContentLength)
299 .and_then(crate::util::parse_content_length)
300 }
301
302 pub fn get<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValue> {
306 self.get_values(name).and_then(HeaderValues::one)
307 }
308
309 pub fn remove<'a>(&mut self, name: impl Into<HeaderName<'a>>) -> Option<HeaderValues> {
312 match name.into().0 {
313 HeaderNameInner::KnownHeader(known) => self.known.remove(&known),
314 HeaderNameInner::UnknownHeader(unknown) => self.unknown.remove(&&unknown),
315 }
316 }
317
318 pub fn get_values<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValues> {
322 match name.into().0 {
323 HeaderNameInner::KnownHeader(known) => self.known.get(&known),
324 HeaderNameInner::UnknownHeader(unknown) => self.unknown.get(&&unknown),
325 }
326 }
327
328 pub fn has_header<'a>(&self, name: impl Into<HeaderName<'a>>) -> bool {
333 match name.into().0 {
334 HeaderNameInner::KnownHeader(known) => self.known.contains_key(&known),
335 HeaderNameInner::UnknownHeader(unknown) => self.unknown.contains_key(&unknown),
336 }
337 }
338
339 pub fn eq_ignore_ascii_case<'a>(
344 &'a self,
345 name: impl Into<HeaderName<'a>>,
346 needle: &str,
347 ) -> bool {
348 self.get_str(name)
349 .is_some_and(|v| v.eq_ignore_ascii_case(needle))
350 }
351
352 pub fn with_inserted_header(
354 mut self,
355 name: impl Into<HeaderName<'static>>,
356 values: impl Into<HeaderValues>,
357 ) -> Self {
358 self.insert(name, values);
359 self
360 }
361
362 pub fn with_appended_header(
364 mut self,
365 name: impl Into<HeaderName<'static>>,
366 values: impl Into<HeaderValues>,
367 ) -> Self {
368 self.append(name, values);
369 self
370 }
371
372 pub fn without_header<'a>(mut self, name: impl Into<HeaderName<'a>>) -> Self {
374 self.remove(name);
375 self
376 }
377
378 pub fn without_headers<'a, I, H>(mut self, names: I) -> Self
380 where
381 I: IntoIterator<Item = H>,
382 H: Into<HeaderName<'a>>,
383 {
384 self.remove_all(names);
385 self
386 }
387
388 pub fn remove_all<'a, I, H>(&mut self, names: I)
390 where
391 I: IntoIterator<Item = H>,
392 H: Into<HeaderName<'a>>,
393 {
394 for name in names {
395 self.remove(name);
396 }
397 }
398}
399
400impl<HN, HV> Extend<(HN, HV)> for Headers
401where
402 HN: Into<HeaderName<'static>>,
403 HV: Into<HeaderValues>,
404{
405 fn extend<T: IntoIterator<Item = (HN, HV)>>(&mut self, iter: T) {
406 for (name, values) in iter {
407 self.append(name, values);
408 }
409 }
410}
411
412impl<HN, HV> FromIterator<(HN, HV)> for Headers
413where
414 HN: Into<HeaderName<'static>>,
415 HV: Into<HeaderValues>,
416{
417 fn from_iter<T: IntoIterator<Item = (HN, HV)>>(iter: T) -> Self {
418 let iter = iter.into_iter();
419 let mut headers = Self::new();
420 for (name, values) in iter {
421 headers.append(name, values);
422 }
423
424 headers
425 }
426}
427
428impl<'a> IntoIterator for &'a Headers {
429 type IntoIter = Iter<'a>;
430 type Item = (HeaderName<'a>, &'a HeaderValues);
431
432 fn into_iter(self) -> Self::IntoIter {
433 self.into()
434 }
435}
436
437#[derive(Debug)]
439pub struct IntoIter {
440 known: btree_map::IntoIter<KnownHeaderName, HeaderValues>,
441 unknown: hash_map::IntoIter<UnknownHeaderName<'static>, HeaderValues>,
442}
443
444impl Iterator for IntoIter {
445 type Item = (HeaderName<'static>, HeaderValues);
446
447 fn next(&mut self) -> Option<Self::Item> {
448 let IntoIter { known, unknown } = self;
449 known
450 .next()
451 .map(|(k, v)| (HeaderName::from(k), v))
452 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(k), v)))
453 }
454}
455
456impl From<Headers> for IntoIter {
457 fn from(value: Headers) -> Self {
458 Self {
459 known: value.known.into_iter(),
460 unknown: value.unknown.into_iter(),
461 }
462 }
463}
464
465#[derive(Debug)]
467pub struct Iter<'a> {
468 known: btree_map::Iter<'a, KnownHeaderName, HeaderValues>,
469 unknown: hash_map::Iter<'a, UnknownHeaderName<'static>, HeaderValues>,
470}
471
472impl<'a> From<&'a Headers> for Iter<'a> {
473 fn from(value: &'a Headers) -> Self {
474 Iter {
475 known: value.known.iter(),
476 unknown: value.unknown.iter(),
477 }
478 }
479}
480
481impl<'a> Iterator for Iter<'a> {
482 type Item = (HeaderName<'a>, &'a HeaderValues);
483
484 fn next(&mut self) -> Option<Self::Item> {
485 let Iter { known, unknown } = self;
486 known
487 .next()
488 .map(|(k, v)| (HeaderName::from(*k), v))
489 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(&**k), v)))
490 }
491}
492
493impl IntoIterator for Headers {
494 type IntoIter = IntoIter;
495 type Item = (HeaderName<'static>, HeaderValues);
496
497 fn into_iter(self) -> Self::IntoIter {
498 self.into()
499 }
500}