1use std::collections::{self, hash_map, hash_map::Entry, VecDeque};
2use std::fmt;
3
4use crate::{HeaderName, HeaderValue};
5
6type HashMap<K, V> = collections::HashMap<K, V, ahash::RandomState>;
7
8#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
11pub enum Either<A, B> {
12 Left(A),
14 Right(B),
16}
17
18#[derive(Clone, PartialEq, Eq)]
24pub struct HeaderMap {
25 pub(crate) inner: HashMap<HeaderName, Value>,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub enum Value {
30 One(HeaderValue),
31 Multi(VecDeque<HeaderValue>),
32}
33
34impl Value {
35 fn get(&self) -> &HeaderValue {
36 match self {
37 Value::One(ref val) => val,
38 Value::Multi(ref val) => &val[0],
39 }
40 }
41
42 fn get_mut(&mut self) -> &mut HeaderValue {
43 match self {
44 Value::One(ref mut val) => val,
45 Value::Multi(ref mut val) => &mut val[0],
46 }
47 }
48
49 pub(crate) fn append(&mut self, val: HeaderValue) {
50 match self {
51 Value::One(prev_val) => {
52 let prev_val = std::mem::replace(prev_val, val);
53 let mut val = VecDeque::new();
54 val.push_back(prev_val);
55 let data = std::mem::replace(self, Value::Multi(val));
56 match data {
57 Value::One(val) => self.append(val),
58 Value::Multi(_) => unreachable!(),
59 }
60 }
61 Value::Multi(ref mut vec) => vec.push_back(val),
62 }
63 }
64}
65
66#[derive(Debug)]
67pub struct ValueIntoIter {
68 value: Value,
69}
70
71impl Iterator for ValueIntoIter {
72 type Item = HeaderValue;
73
74 fn next(&mut self) -> Option<Self::Item> {
75 match &mut self.value {
76 Value::One(_) => {
77 let val = std::mem::replace(
78 &mut self.value,
79 Value::Multi(VecDeque::with_capacity(0)),
80 );
81 match val {
82 Value::One(val) => Some(val),
83 _ => unreachable!(),
84 }
85 }
86 Value::Multi(vec) => vec.pop_front(),
87 }
88 }
89
90 fn size_hint(&self) -> (usize, Option<usize>) {
91 match self.value {
92 Value::One(_) => (1, None),
93 Value::Multi(ref v) => v.iter().size_hint(),
94 }
95 }
96}
97
98impl IntoIterator for Value {
99 type Item = HeaderValue;
100 type IntoIter = ValueIntoIter;
101
102 #[inline]
103 fn into_iter(self) -> Self::IntoIter {
104 ValueIntoIter { value: self }
105 }
106}
107
108impl Extend<HeaderValue> for Value {
109 #[inline]
110 fn extend<T>(&mut self, iter: T)
111 where
112 T: IntoIterator<Item = HeaderValue>,
113 {
114 for h in iter.into_iter() {
115 self.append(h);
116 }
117 }
118}
119
120impl From<HeaderValue> for Value {
121 #[inline]
122 fn from(hdr: HeaderValue) -> Value {
123 Value::One(hdr)
124 }
125}
126
127impl<'a> From<&'a HeaderValue> for Value {
128 #[inline]
129 fn from(hdr: &'a HeaderValue) -> Value {
130 Value::One(hdr.clone())
131 }
132}
133
134impl Default for HeaderMap {
135 #[inline]
136 fn default() -> Self {
137 Self::new()
138 }
139}
140
141impl HeaderMap {
142 pub fn new() -> Self {
147 HeaderMap {
148 inner: HashMap::default(),
149 }
150 }
151
152 pub fn with_capacity(capacity: usize) -> HeaderMap {
161 HeaderMap {
162 inner: HashMap::with_capacity_and_hasher(capacity, Default::default()),
163 }
164 }
165
166 pub fn len(&self) -> usize {
171 self.inner.len()
172 }
173
174 pub fn is_empty(&self) -> bool {
176 self.inner.len() == 0
177 }
178
179 pub fn clear(&mut self) {
182 self.inner.clear();
183 }
184
185 pub fn capacity(&self) -> usize {
190 self.inner.capacity()
191 }
192
193 pub fn reserve(&mut self, additional: usize) {
202 self.inner.reserve(additional)
203 }
204
205 pub fn get<N: AsName>(&self, name: N) -> Option<&HeaderValue> {
211 self.get2(name).map(|v| v.get())
212 }
213
214 fn get2<N: AsName>(&self, name: N) -> Option<&Value> {
215 match name.as_name() {
216 Either::Left(name) => self.inner.get(name),
217 Either::Right(s) => {
218 if let Ok(name) = HeaderName::try_from(s) {
219 self.inner.get(&name)
220 } else {
221 None
222 }
223 }
224 }
225 }
226
227 pub fn get_all<N: AsName>(&self, name: N) -> GetAll<'_> {
235 GetAll {
236 idx: 0,
237 item: self.get2(name),
238 }
239 }
240
241 pub fn get_mut<N: AsName>(&mut self, name: N) -> Option<&mut HeaderValue> {
247 match name.as_name() {
248 Either::Left(name) => self.inner.get_mut(name).map(|v| v.get_mut()),
249 Either::Right(s) => {
250 if let Ok(name) = HeaderName::try_from(s) {
251 self.inner.get_mut(&name).map(|v| v.get_mut())
252 } else {
253 None
254 }
255 }
256 }
257 }
258
259 pub fn contains_key<N: AsName>(&self, key: N) -> bool {
261 match key.as_name() {
262 Either::Left(name) => self.inner.contains_key(name),
263 Either::Right(s) => {
264 if let Ok(name) = HeaderName::try_from(s) {
265 self.inner.contains_key(&name)
266 } else {
267 false
268 }
269 }
270 }
271 }
272
273 pub fn iter(&self) -> Iter<'_> {
279 Iter::new(self.inner.iter())
280 }
281
282 #[doc(hidden)]
283 pub fn iter_inner(&self) -> hash_map::Iter<'_, HeaderName, Value> {
284 self.inner.iter()
285 }
286
287 pub fn keys(&self) -> Keys<'_> {
293 Keys(self.inner.keys())
294 }
295
296 pub fn insert(&mut self, key: HeaderName, val: HeaderValue) {
311 let _ = self.inner.insert(key, Value::One(val));
312 }
313
314 pub fn append(&mut self, key: HeaderName, value: HeaderValue) {
324 match self.inner.entry(key) {
325 Entry::Occupied(mut entry) => entry.get_mut().append(value),
326 Entry::Vacant(entry) => {
327 entry.insert(Value::One(value));
328 }
329 }
330 }
331
332 pub fn remove<N: AsName>(&mut self, key: N) {
334 match key.as_name() {
335 Either::Left(name) => {
336 let _ = self.inner.remove(name);
337 }
338 Either::Right(s) => {
339 if let Ok(name) = HeaderName::try_from(s) {
340 let _ = self.inner.remove(&name);
341 }
342 }
343 }
344 }
345}
346
347#[doc(hidden)]
348pub trait AsName {
349 fn as_name(&self) -> Either<&HeaderName, &str>;
350}
351
352impl AsName for HeaderName {
353 fn as_name(&self) -> Either<&HeaderName, &str> {
354 Either::Left(self)
355 }
356}
357
358impl AsName for &HeaderName {
359 fn as_name(&self) -> Either<&HeaderName, &str> {
360 Either::Left(self)
361 }
362}
363
364impl AsName for &str {
365 fn as_name(&self) -> Either<&HeaderName, &str> {
366 Either::Right(self)
367 }
368}
369
370impl AsName for String {
371 fn as_name(&self) -> Either<&HeaderName, &str> {
372 Either::Right(self.as_str())
373 }
374}
375
376impl AsName for &String {
377 fn as_name(&self) -> Either<&HeaderName, &str> {
378 Either::Right(self.as_str())
379 }
380}
381
382impl<N: std::fmt::Display, V> FromIterator<(N, V)> for HeaderMap
383where
384 HeaderName: TryFrom<N>,
385 Value: TryFrom<V>,
386 V: std::fmt::Debug,
387{
388 #[inline]
389 #[allow(clippy::mutable_key_type)]
390 fn from_iter<T: IntoIterator<Item = (N, V)>>(iter: T) -> Self {
391 let map = iter
392 .into_iter()
393 .filter_map(|(n, v)| {
394 let name = format!("{n}");
395 match (HeaderName::try_from(n), Value::try_from(v)) {
396 (Ok(n), Ok(v)) => Some((n, v)),
397 (Ok(n), Err(_)) => {
398 log::warn!("failed to parse `{n}` header value");
399 None
400 }
401 (Err(_), Ok(_)) => {
402 log::warn!("invalid HTTP header name: {name}");
403 None
404 }
405 (Err(_), Err(_)) => {
406 log::warn!("invalid HTTP header name `{name}` and value");
407 None
408 }
409 }
410 })
411 .fold(HashMap::default(), |mut map: HashMap<_, Value>, (n, v)| {
412 match map.entry(n) {
413 Entry::Occupied(mut oc) => oc.get_mut().extend(v),
414 Entry::Vacant(va) => {
415 let _ = va.insert(v);
416 }
417 }
418 map
419 });
420 HeaderMap { inner: map }
421 }
422}
423
424impl FromIterator<HeaderValue> for Value {
425 fn from_iter<T: IntoIterator<Item = HeaderValue>>(iter: T) -> Self {
426 let mut iter = iter.into_iter();
427 let value = iter.next().map(Value::One);
428 let mut value = match value {
429 Some(v) => v,
430 _ => Value::One(HeaderValue::from_static("")),
431 };
432 value.extend(iter);
433 value
434 }
435}
436
437impl TryFrom<&str> for Value {
438 type Error = crate::header::InvalidHeaderValue;
439 fn try_from(value: &str) -> Result<Self, Self::Error> {
440 Ok(value
441 .split(',')
442 .filter(|v| !v.is_empty())
443 .map(|v| v.trim())
444 .filter_map(|v| HeaderValue::from_str(v).ok())
445 .collect::<Value>())
446 }
447}
448
449#[derive(Debug)]
450pub struct GetAll<'a> {
451 idx: usize,
452 item: Option<&'a Value>,
453}
454
455impl<'a> Iterator for GetAll<'a> {
456 type Item = &'a HeaderValue;
457
458 #[inline]
459 fn next(&mut self) -> Option<&'a HeaderValue> {
460 if let Some(ref val) = self.item {
461 match val {
462 Value::One(ref val) => {
463 self.item.take();
464 Some(val)
465 }
466 Value::Multi(ref vec) => {
467 if self.idx < vec.len() {
468 let item = Some(&vec[self.idx]);
469 self.idx += 1;
470 item
471 } else {
472 self.item.take();
473 None
474 }
475 }
476 }
477 } else {
478 None
479 }
480 }
481}
482
483#[derive(Debug)]
484pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>);
485
486impl<'a> Iterator for Keys<'a> {
487 type Item = &'a HeaderName;
488
489 #[inline]
490 fn next(&mut self) -> Option<&'a HeaderName> {
491 self.0.next()
492 }
493}
494
495impl<'a> IntoIterator for &'a HeaderMap {
496 type Item = (&'a HeaderName, &'a HeaderValue);
497 type IntoIter = Iter<'a>;
498
499 fn into_iter(self) -> Self::IntoIter {
500 self.iter()
501 }
502}
503
504#[derive(Debug)]
505pub struct Iter<'a> {
506 idx: usize,
507 current: Option<(&'a HeaderName, &'a VecDeque<HeaderValue>)>,
508 iter: hash_map::Iter<'a, HeaderName, Value>,
509}
510
511impl<'a> Iter<'a> {
512 fn new(iter: hash_map::Iter<'a, HeaderName, Value>) -> Self {
513 Self {
514 iter,
515 idx: 0,
516 current: None,
517 }
518 }
519}
520
521impl<'a> Iterator for Iter<'a> {
522 type Item = (&'a HeaderName, &'a HeaderValue);
523
524 #[inline]
525 fn next(&mut self) -> Option<(&'a HeaderName, &'a HeaderValue)> {
526 if let Some(ref mut item) = self.current {
527 if self.idx < item.1.len() {
528 let item = (item.0, &item.1[self.idx]);
529 self.idx += 1;
530 return Some(item);
531 } else {
532 self.idx = 0;
533 self.current.take();
534 }
535 }
536 if let Some(item) = self.iter.next() {
537 match item.1 {
538 Value::One(ref value) => Some((item.0, value)),
539 Value::Multi(ref vec) => {
540 self.current = Some((item.0, vec));
541 self.next()
542 }
543 }
544 } else {
545 None
546 }
547 }
548}
549
550impl fmt::Debug for HeaderMap {
551 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552 let mut f = f.debug_map();
553
554 for (key, val) in self.inner.iter() {
555 match val {
556 Value::One(val) => {
557 let _ = f.entry(&key, &val);
558 }
559 Value::Multi(val) => {
560 for v in val {
561 f.entry(&key, &v);
562 }
563 }
564 }
565 }
566 f.finish()
567 }
568}
569
570#[cfg(test)]
571mod tests {
572 use super::*;
573 use crate::header::{ACCEPT_ENCODING, CONTENT_TYPE};
574
575 #[test]
576 fn test_from_iter() {
577 let vec = vec![
578 ("Connection", "keep-alive"),
579 ("Accept", "text/html"),
580 (
581 "Accept",
582 "*/*, application/xhtml+xml, application/xml;q=0.9, image/webp,",
583 ),
584 ];
585 let map = HeaderMap::from_iter(vec);
586 assert_eq!(
587 map.get("Connection"),
588 Some(&HeaderValue::from_static("keep-alive"))
589 );
590 assert_eq!(
591 map.get_all("Accept").collect::<Vec<&HeaderValue>>(),
592 vec![
593 &HeaderValue::from_static("text/html"),
594 &HeaderValue::from_static("*/*"),
595 &HeaderValue::from_static("application/xhtml+xml"),
596 &HeaderValue::from_static("application/xml;q=0.9"),
597 &HeaderValue::from_static("image/webp"),
598 ]
599 )
600 }
601
602 #[test]
603 #[allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args)]
604 fn test_basics() {
605 let m = HeaderMap::default();
606 assert!(m.is_empty());
607 let mut m = HeaderMap::with_capacity(10);
608 assert!(m.is_empty());
609 assert!(m.capacity() >= 10);
610 m.reserve(20);
611 assert!(m.capacity() >= 20);
612
613 m.insert(CONTENT_TYPE, HeaderValue::from_static("text"));
614 assert!(m.contains_key(CONTENT_TYPE));
615 assert!(m.contains_key("content-type"));
616 assert!(m.contains_key("content-type".to_string()));
617 assert!(m.contains_key(&("content-type".to_string())));
618 assert_eq!(
619 *m.get_mut("content-type").unwrap(),
620 HeaderValue::from_static("text")
621 );
622 assert_eq!(
623 *m.get_mut(CONTENT_TYPE).unwrap(),
624 HeaderValue::from_static("text")
625 );
626 assert!(format!("{m:?}").contains("content-type"));
627
628 assert!(m.keys().any(|x| x == CONTENT_TYPE));
629 m.remove("content-type");
630 assert!(m.is_empty());
631 }
632
633 #[test]
634 fn test_append() {
635 let mut map = HeaderMap::new();
636
637 map.append(ACCEPT_ENCODING, HeaderValue::from_static("gzip"));
638 assert_eq!(
639 map.get_all(ACCEPT_ENCODING).collect::<Vec<_>>(),
640 vec![&HeaderValue::from_static("gzip"),]
641 );
642
643 map.append(ACCEPT_ENCODING, HeaderValue::from_static("br"));
644 map.append(ACCEPT_ENCODING, HeaderValue::from_static("deflate"));
645 assert_eq!(
646 map.get_all(ACCEPT_ENCODING).collect::<Vec<_>>(),
647 vec![
648 &HeaderValue::from_static("gzip"),
649 &HeaderValue::from_static("br"),
650 &HeaderValue::from_static("deflate"),
651 ]
652 );
653 assert_eq!(
654 map.get(ACCEPT_ENCODING),
655 Some(&HeaderValue::from_static("gzip"))
656 );
657 assert_eq!(
658 map.get_mut(ACCEPT_ENCODING),
659 Some(&mut HeaderValue::from_static("gzip"))
660 );
661
662 map.remove(ACCEPT_ENCODING);
663 assert_eq!(map.get(ACCEPT_ENCODING), None);
664 }
665
666 #[test]
667 fn test_from_http() {
668 let mut map = http::HeaderMap::new();
669 map.append(ACCEPT_ENCODING, http::HeaderValue::from_static("gzip"));
670
671 let map2 = HeaderMap::from(map);
672 assert_eq!(
673 map2.get(ACCEPT_ENCODING),
674 Some(&HeaderValue::from_static("gzip"))
675 );
676 }
677}