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
90#[cfg(feature = "parse")]
91impl Headers {
92 #[doc(hidden)]
93 pub fn extend_parse(&mut self, bytes: &[u8]) -> Result<usize, crate::Error> {
94 use memchr::memmem::Finder;
95
96 let mut new_header_count = 0;
97 let mut last_line = 0;
98 for newline in Finder::new(b"\r\n").find_iter(bytes) {
99 if newline == last_line {
100 continue;
101 }
102
103 let line = &bytes[last_line..newline];
104 let colon = memchr::memchr(b':', line).ok_or(crate::Error::InvalidHead)?;
105
106 let header_name = HeaderName::parse(&line[..colon])?.to_owned();
107
108 let token_end = last_line + colon;
109
110 let mut value_start = token_end + 1;
111
112 while bytes
113 .get(value_start)
114 .is_some_and(|b| matches!(b, b'\t' | b' '))
115 {
116 value_start += 1;
117 }
118
119 let header_value = HeaderValue::parse(bytes[value_start..newline].trim_ascii_end());
120 self.append(header_name, header_value);
121 new_header_count += 1;
122 last_line = newline + 2;
123 }
124 Ok(new_header_count)
125 }
126
127 #[doc(hidden)]
128 pub fn parse(bytes: &[u8]) -> Result<Self, crate::Error> {
129 let mut headers = Headers::new();
130 headers.extend_parse(bytes)?;
131 Ok(headers)
132 }
133}
134
135impl Headers {
136 pub fn new() -> Self {
138 Self::default()
139 }
140
141 pub fn iter(&self) -> Iter<'_> {
145 self.into()
146 }
147
148 pub fn is_empty(&self) -> bool {
150 self.known.is_empty() && self.unknown.is_empty()
151 }
152
153 pub fn len(&self) -> usize {
156 self.known.len() + self.unknown.len()
157 }
158
159 pub fn append(
166 &mut self,
167 name: impl Into<HeaderName<'static>>,
168 values: impl Into<HeaderValues>,
169 ) -> &mut HeaderValues {
170 self.entry(name).append(values)
171 }
172
173 pub fn append_all(&mut self, other: Headers) {
176 for (name, value) in other.known {
177 match self.known.entry(name) {
178 BTreeEntry::Occupied(mut entry) => {
179 entry.get_mut().extend(value);
180 }
181 BTreeEntry::Vacant(entry) => {
182 entry.insert(value);
183 }
184 }
185 }
186
187 for (name, value) in other.unknown {
188 match self.unknown.entry(name) {
189 HashbrownEntry::Occupied(mut entry) => {
190 entry.get_mut().extend(value);
191 }
192 HashbrownEntry::Vacant(entry) => {
193 entry.insert(value);
194 }
195 }
196 }
197 }
198
199 pub fn insert_all(&mut self, other: Headers) {
201 for (name, value) in other.known {
202 self.known.insert(name, value);
203 }
204
205 for (name, value) in other.unknown {
206 self.unknown.insert(name, value);
207 }
208 }
209
210 pub fn insert(
214 &mut self,
215 name: impl Into<HeaderName<'static>>,
216 values: impl Into<HeaderValues>,
217 ) -> &mut Self {
218 self.entry(name).insert(values);
219 self
220 }
221
222 pub fn try_insert(
227 &mut self,
228 name: impl Into<HeaderName<'static>>,
229 values: impl Into<HeaderValues>,
230 ) -> &mut Self {
231 self.entry(name).or_insert(values);
232 self
233 }
234
235 pub fn try_insert_with<V>(
240 &mut self,
241 name: impl Into<HeaderName<'static>>,
242 values: impl FnOnce() -> V,
243 ) -> &mut HeaderValues
244 where
245 V: Into<HeaderValues>,
246 {
247 self.entry(name).or_insert_with(values)
248 }
249
250 pub fn entry(&mut self, name: impl Into<HeaderName<'static>>) -> Entry<'_> {
254 match name.into().0 {
255 HeaderNameInner::KnownHeader(known) => match self.known.entry(known) {
256 BTreeEntry::Vacant(vacant) => {
257 Entry::Vacant(VacantEntry(VacantEntryInner::Known(vacant)))
258 }
259 BTreeEntry::Occupied(occupied) => {
260 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Known(occupied)))
261 }
262 },
263
264 HeaderNameInner::UnknownHeader(unknown) => match self.unknown.entry(unknown) {
265 HashbrownEntry::Occupied(occupied) => {
266 Entry::Occupied(OccupiedEntry(OccupiedEntryInner::Unknown(occupied)))
267 }
268
269 HashbrownEntry::Vacant(vacant) => {
270 Entry::Vacant(VacantEntry(VacantEntryInner::Unknown(vacant)))
271 }
272 },
273 }
274 }
275
276 pub fn get_str<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&str> {
282 self.get_values(name).and_then(HeaderValues::as_str)
283 }
284
285 pub fn get<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValue> {
289 self.get_values(name).and_then(HeaderValues::one)
290 }
291
292 pub fn remove<'a>(&mut self, name: impl Into<HeaderName<'a>>) -> Option<HeaderValues> {
295 match name.into().0 {
296 HeaderNameInner::KnownHeader(known) => self.known.remove(&known),
297 HeaderNameInner::UnknownHeader(unknown) => self.unknown.remove(&&unknown),
298 }
299 }
300
301 pub fn get_values<'a>(&self, name: impl Into<HeaderName<'a>>) -> Option<&HeaderValues> {
305 match name.into().0 {
306 HeaderNameInner::KnownHeader(known) => self.known.get(&known),
307 HeaderNameInner::UnknownHeader(unknown) => self.unknown.get(&&unknown),
308 }
309 }
310
311 pub fn has_header<'a>(&self, name: impl Into<HeaderName<'a>>) -> bool {
316 match name.into().0 {
317 HeaderNameInner::KnownHeader(known) => self.known.contains_key(&known),
318 HeaderNameInner::UnknownHeader(unknown) => self.unknown.contains_key(&unknown),
319 }
320 }
321
322 pub fn eq_ignore_ascii_case<'a>(
327 &'a self,
328 name: impl Into<HeaderName<'a>>,
329 needle: &str,
330 ) -> bool {
331 self.get_str(name)
332 .is_some_and(|v| v.eq_ignore_ascii_case(needle))
333 }
334
335 pub fn with_inserted_header(
337 mut self,
338 name: impl Into<HeaderName<'static>>,
339 values: impl Into<HeaderValues>,
340 ) -> Self {
341 self.insert(name, values);
342 self
343 }
344
345 pub fn with_appended_header(
347 mut self,
348 name: impl Into<HeaderName<'static>>,
349 values: impl Into<HeaderValues>,
350 ) -> Self {
351 self.append(name, values);
352 self
353 }
354
355 pub fn without_header<'a>(mut self, name: impl Into<HeaderName<'a>>) -> Self {
357 self.remove(name);
358 self
359 }
360
361 pub fn without_headers<'a, I, H>(mut self, names: I) -> Self
363 where
364 I: IntoIterator<Item = H>,
365 H: Into<HeaderName<'a>>,
366 {
367 self.remove_all(names);
368 self
369 }
370
371 pub fn remove_all<'a, I, H>(&mut self, names: I)
373 where
374 I: IntoIterator<Item = H>,
375 H: Into<HeaderName<'a>>,
376 {
377 for name in names {
378 self.remove(name);
379 }
380 }
381}
382
383impl<HN, HV> Extend<(HN, HV)> for Headers
384where
385 HN: Into<HeaderName<'static>>,
386 HV: Into<HeaderValues>,
387{
388 fn extend<T: IntoIterator<Item = (HN, HV)>>(&mut self, iter: T) {
389 for (name, values) in iter {
390 self.append(name, values);
391 }
392 }
393}
394
395impl<HN, HV> FromIterator<(HN, HV)> for Headers
396where
397 HN: Into<HeaderName<'static>>,
398 HV: Into<HeaderValues>,
399{
400 fn from_iter<T: IntoIterator<Item = (HN, HV)>>(iter: T) -> Self {
401 let iter = iter.into_iter();
402 let mut headers = Self::new();
403 for (name, values) in iter {
404 headers.append(name, values);
405 }
406
407 headers
408 }
409}
410
411impl<'a> IntoIterator for &'a Headers {
412 type IntoIter = Iter<'a>;
413 type Item = (HeaderName<'a>, &'a HeaderValues);
414
415 fn into_iter(self) -> Self::IntoIter {
416 self.into()
417 }
418}
419
420#[derive(Debug)]
422pub struct IntoIter {
423 known: btree_map::IntoIter<KnownHeaderName, HeaderValues>,
424 unknown: hash_map::IntoIter<UnknownHeaderName<'static>, HeaderValues>,
425}
426
427impl Iterator for IntoIter {
428 type Item = (HeaderName<'static>, HeaderValues);
429
430 fn next(&mut self) -> Option<Self::Item> {
431 let IntoIter { known, unknown } = self;
432 known
433 .next()
434 .map(|(k, v)| (HeaderName::from(k), v))
435 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(k), v)))
436 }
437}
438
439impl From<Headers> for IntoIter {
440 fn from(value: Headers) -> Self {
441 Self {
442 known: value.known.into_iter(),
443 unknown: value.unknown.into_iter(),
444 }
445 }
446}
447
448#[derive(Debug)]
450pub struct Iter<'a> {
451 known: btree_map::Iter<'a, KnownHeaderName, HeaderValues>,
452 unknown: hash_map::Iter<'a, UnknownHeaderName<'static>, HeaderValues>,
453}
454
455impl<'a> From<&'a Headers> for Iter<'a> {
456 fn from(value: &'a Headers) -> Self {
457 Iter {
458 known: value.known.iter(),
459 unknown: value.unknown.iter(),
460 }
461 }
462}
463
464impl<'a> Iterator for Iter<'a> {
465 type Item = (HeaderName<'a>, &'a HeaderValues);
466
467 fn next(&mut self) -> Option<Self::Item> {
468 let Iter { known, unknown } = self;
469 known
470 .next()
471 .map(|(k, v)| (HeaderName::from(*k), v))
472 .or_else(|| unknown.next().map(|(k, v)| (HeaderName::from(&**k), v)))
473 }
474}
475
476impl IntoIterator for Headers {
477 type IntoIter = IntoIter;
478 type Item = (HeaderName<'static>, HeaderValues);
479
480 fn into_iter(self) -> Self::IntoIter {
481 self.into()
482 }
483}