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