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 smallvec::SmallVec;
40use std::fmt::{self, Debug, Display, Formatter};
41use unknown_header_name::UnknownHeaderName;
42
43#[derive(Debug, Clone, PartialEq, Eq, Default)]
45#[must_use]
46pub struct Headers {
47 pub(crate) known: HashMap<KnownHeaderName, HeaderValues>,
48 pub(crate) unknown: HashMap<UnknownHeaderName<'static>, HeaderValues>,
49}
50
51pub const SERVER_HEADER: HeaderValue =
53 HeaderValue::const_new(concat!("trillium-http/", env!("CARGO_PKG_VERSION")));
54
55#[cfg(feature = "serde")]
56impl serde::Serialize for Headers {
57 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: serde::Serializer,
60 {
61 use serde::ser::SerializeMap;
62 let mut map = serializer.serialize_map(Some(self.len()))?;
63 for (key, values) in self {
64 map.serialize_entry(&key, values)?;
65 }
66 map.end()
67 }
68}
69
70impl Display for Headers {
71 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
72 let mut data = self.iter().collect::<Vec<_>>();
75 data.sort_by(|(a, _), (b, _)| a.cmp(b));
76 for (n, v) in data {
77 for v in v {
78 f.write_fmt(format_args!("{n}: {v}\r\n"))?;
79 }
80 }
81 Ok(())
82 }
83}
84
85impl Headers {
86 pub(crate) fn clear(&mut self) {
87 self.known.clear();
88 self.unknown.clear();
89 }
90
91 #[doc(hidden)]
95 pub fn with_capacities(known: usize, unknown: usize) -> Self {
96 Self {
97 known: HashMap::with_capacity(known),
98 unknown: HashMap::with_capacity(unknown),
99 }
100 }
101
102 #[doc(hidden)]
103 pub fn extend_parse(&mut self, bytes: &[u8]) -> Result<usize, crate::Error> {
104 use memchr::memmem::Finder;
105
106 let mut new_header_count = 0;
107 let mut last_line = 0;
108 for newline in Finder::new(b"\r\n").find_iter(bytes) {
109 if newline == last_line {
110 continue;
111 }
112
113 let line = &bytes[last_line..newline];
114
115 let colon = memchr::memchr(b':', line).ok_or(crate::Error::InvalidHeaderName)?;
121 let name = HeaderName::parse(&line[..colon])?;
122 if !name.is_valid() {
123 return Err(crate::Error::InvalidHeaderName);
124 }
125
126 let mut value_start = colon + 1;
127 while line
128 .get(value_start)
129 .is_some_and(|b| matches!(b, b'\t' | b' '))
130 {
131 value_start += 1;
132 }
133 let value_bytes = line[value_start..].trim_ascii_end();
134 if !value_bytes.iter().all(|&b| b >= 0x20 || b == b'\t') {
136 return Err(crate::Error::InvalidHeaderValue(name.to_owned()));
137 }
138
139 self.append(name.to_owned(), HeaderValue::parse(value_bytes));
140 new_header_count += 1;
141 last_line = newline + 2;
142 }
143 Ok(new_header_count)
144 }
145
146 #[doc(hidden)]
147 pub fn parse(bytes: &[u8]) -> Result<Self, crate::Error> {
148 let mut headers = Headers::new();
149 headers.extend_parse(bytes)?;
150 Ok(headers)
151 }
152}
153
154impl Headers {
155 pub fn new() -> Self {
157 Self::default()
158 }
159
160 pub fn iter(&self) -> Iter<'_> {
165 self.into()
166 }
167
168 pub fn is_empty(&self) -> bool {
170 self.known.is_empty() && self.unknown.is_empty()
171 }
172
173 pub fn len(&self) -> usize {
176 self.known.len() + self.unknown.len()
177 }
178
179 pub fn append(
186 &mut self,
187 name: impl Into<HeaderName<'static>>,
188 values: impl Into<HeaderValues>,
189 ) -> &mut HeaderValues {
190 self.entry(name).append(values)
191 }
192
193 pub fn append_all(&mut self, other: Headers) {
196 for (name, value) in other.known {
197 match self.known.entry(name) {
198 HashbrownEntry::Occupied(mut entry) => {
199 entry.get_mut().extend(value);
200 }
201 HashbrownEntry::Vacant(entry) => {
202 entry.insert(value);
203 }
204 }
205 }
206
207 for (name, value) in other.unknown {
208 match self.unknown.entry(name) {
209 HashbrownEntry::Occupied(mut entry) => {
210 entry.get_mut().extend(value);
211 }
212 HashbrownEntry::Vacant(entry) => {
213 entry.insert(value);
214 }
215 }
216 }
217 }
218
219 pub fn insert_all(&mut self, other: Headers) {
221 for (name, value) in other.known {
222 self.known.insert(name, value);
223 }
224
225 for (name, value) in other.unknown {
226 self.unknown.insert(name, value);
227 }
228 }
229
230 pub fn insert(
234 &mut self,
235 name: impl Into<HeaderName<'static>>,
236 values: impl Into<HeaderValues>,
237 ) -> &mut Self {
238 self.entry(name).insert(values);
239 self
240 }
241
242 pub fn try_insert(
247 &mut self,
248 name: impl Into<HeaderName<'static>>,
249 values: impl Into<HeaderValues>,
250 ) -> &mut Self {
251 self.entry(name).or_insert(values);
252 self
253 }
254
255 pub fn try_insert_with<V>(
260 &mut self,
261 name: impl Into<HeaderName<'static>>,
262 values: impl FnOnce() -> V,
263 ) -> &mut HeaderValues
264 where
265 V: Into<HeaderValues>,
266 {
267 self.entry(name).or_insert_with(values)
268 }
269
270 pub fn entry(&mut self, name: impl Into<HeaderName<'static>>) -> Entry<'_> {
274 match name.into().0 {
275 HeaderNameInner::KnownHeader(known) => match self.known.entry(known) {
276 HashbrownEntry::Vacant(vacant) => {
277 Entry::Vacant(VacantEntry(VacantEntryInner::Known(vacant)))
278 }
279 HashbrownEntry::Occupied(occupied) => {
280 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Known(occupied)))
281 }
282 },
283
284 HeaderNameInner::UnknownHeader(unknown) => match self.unknown.entry(unknown) {
285 HashbrownEntry::Occupied(occupied) => {
286 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Unknown(occupied)))
287 }
288
289 HashbrownEntry::Vacant(vacant) => {
290 Entry::Vacant(VacantEntry(VacantEntryInner::Unknown(vacant)))
291 }
292 },
293 }
294 }
295
296 pub fn get_str<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&str> {
302 self.get_values(name).and_then(HeaderValues::as_str)
303 }
304
305 pub fn content_length(&self) -> Option<u64> {
310 self.get_values(KnownHeaderName::ContentLength)
311 .and_then(crate::util::parse_content_length)
312 }
313
314 pub fn get<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValue> {
318 self.get_values(name).and_then(HeaderValues::one)
319 }
320
321 pub fn remove<'a>(&mut self, name: impl Into<HeaderName<'a>>) -> Option<HeaderValues> {
324 match name.into().0 {
325 HeaderNameInner::KnownHeader(known) => self.known.remove(&known),
326 HeaderNameInner::UnknownHeader(unknown) => self.unknown.remove(&&unknown),
327 }
328 }
329
330 pub fn get_values<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValues> {
334 match name.into().0 {
335 HeaderNameInner::KnownHeader(known) => self.known.get(&known),
336 HeaderNameInner::UnknownHeader(unknown) => self.unknown.get(&&unknown),
337 }
338 }
339
340 pub fn has_header<'a>(&self, name: impl Into<HeaderName<'a>>) -> bool {
345 match name.into().0 {
346 HeaderNameInner::KnownHeader(known) => self.known.contains_key(&known),
347 HeaderNameInner::UnknownHeader(unknown) => self.unknown.contains_key(&unknown),
348 }
349 }
350
351 pub fn eq_ignore_ascii_case<'a>(
356 &'a self,
357 name: impl Into<HeaderName<'a>>,
358 needle: &str,
359 ) -> bool {
360 self.get_str(name)
361 .is_some_and(|v| v.eq_ignore_ascii_case(needle))
362 }
363
364 pub fn token_iter<'a>(
376 &'a self,
377 name: impl Into<HeaderName<'a>>,
378 ) -> impl Iterator<Item = &'a str> {
379 self.get_values(name)
380 .into_iter()
381 .flatten()
382 .filter_map(|value| value.as_str())
383 .flat_map(|value| value.split(','))
384 .map(str::trim)
385 .filter(|token| !token.is_empty())
386 }
387
388 pub fn with_inserted_header(
390 mut self,
391 name: impl Into<HeaderName<'static>>,
392 values: impl Into<HeaderValues>,
393 ) -> Self {
394 self.insert(name, values);
395 self
396 }
397
398 pub fn with_appended_header(
400 mut self,
401 name: impl Into<HeaderName<'static>>,
402 values: impl Into<HeaderValues>,
403 ) -> Self {
404 self.append(name, values);
405 self
406 }
407
408 pub fn without_header<'a>(mut self, name: impl Into<HeaderName<'a>>) -> Self {
410 self.remove(name);
411 self
412 }
413
414 pub fn without_headers<'a, I, H>(mut self, names: I) -> Self
416 where
417 I: IntoIterator<Item = H>,
418 H: Into<HeaderName<'a>>,
419 {
420 self.remove_all(names);
421 self
422 }
423
424 pub fn remove_all<'a, I, H>(&mut self, names: I)
426 where
427 I: IntoIterator<Item = H>,
428 H: Into<HeaderName<'a>>,
429 {
430 for name in names {
431 self.remove(name);
432 }
433 }
434}
435
436impl<HN, HV> Extend<(HN, HV)> for Headers
437where
438 HN: Into<HeaderName<'static>>,
439 HV: Into<HeaderValues>,
440{
441 fn extend<T: IntoIterator<Item = (HN, HV)>>(&mut self, iter: T) {
442 for (name, values) in iter {
443 self.append(name, values);
444 }
445 }
446}
447
448impl<HN, HV> FromIterator<(HN, HV)> for Headers
449where
450 HN: Into<HeaderName<'static>>,
451 HV: Into<HeaderValues>,
452{
453 fn from_iter<T: IntoIterator<Item = (HN, HV)>>(iter: T) -> Self {
454 let iter = iter.into_iter();
455 let mut headers = Self::new();
456 for (name, values) in iter {
457 headers.append(name, values);
458 }
459
460 headers
461 }
462}
463
464impl<'a> IntoIterator for &'a Headers {
465 type IntoIter = Iter<'a>;
466 type Item = (HeaderName<'a>, &'a HeaderValues);
467
468 fn into_iter(self) -> Self::IntoIter {
469 self.into()
470 }
471}
472
473#[derive(Debug)]
475pub struct IntoIter {
476 known: hash_map::IntoIter<KnownHeaderName, HeaderValues>,
477 unknown: hash_map::IntoIter<UnknownHeaderName<'static>, HeaderValues>,
478}
479
480impl Iterator for IntoIter {
481 type Item = (HeaderName<'static>, HeaderValues);
482
483 fn next(&mut self) -> Option<Self::Item> {
484 let IntoIter { known, unknown } = self;
485 known
486 .next()
487 .map(|(k, v)| (HeaderName::from(k), v))
488 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(k), v)))
489 }
490}
491
492impl From<Headers> for IntoIter {
493 fn from(value: Headers) -> Self {
494 Self {
495 known: value.known.into_iter(),
496 unknown: value.unknown.into_iter(),
497 }
498 }
499}
500
501#[derive(Debug)]
503pub struct Iter<'a> {
504 known: smallvec::IntoIter<[(KnownHeaderName, &'a HeaderValues); 16]>,
508 unknown: hash_map::Iter<'a, UnknownHeaderName<'static>, HeaderValues>,
509}
510
511impl<'a> From<&'a Headers> for Iter<'a> {
512 fn from(value: &'a Headers) -> Self {
513 let mut known = value
514 .known
515 .iter()
516 .map(|(k, v)| (*k, v))
517 .collect::<SmallVec<[(KnownHeaderName, &'a HeaderValues); 16]>>();
518 known.sort_unstable_by_key(|(name, _)| *name);
519 Iter {
520 known: known.into_iter(),
521 unknown: value.unknown.iter(),
522 }
523 }
524}
525
526impl<'a> Iterator for Iter<'a> {
527 type Item = (HeaderName<'a>, &'a HeaderValues);
528
529 fn next(&mut self) -> Option<Self::Item> {
530 let Iter { known, unknown } = self;
531 known
532 .next()
533 .map(|(k, v)| (HeaderName::from(k), v))
534 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(&**k), v)))
535 }
536}
537
538impl IntoIterator for Headers {
539 type IntoIter = IntoIter;
540 type Item = (HeaderName<'static>, HeaderValues);
541
542 fn into_iter(self) -> Self::IntoIter {
543 self.into()
544 }
545}