From 84ea9e7e8849d98108a66990f8508fc014d78d19 Mon Sep 17 00:00:00 2001
From: Thales <thales.fragosoz@gmail.com>
Date: Fri, 17 Dec 2021 21:05:12 -0300
Subject: [PATCH] http: Replace header::map::GetAll with std::slice::Iter
 (#2527)

---
 actix-http/CHANGES.md        |  4 +++
 actix-http/src/header/map.rs | 55 ++++--------------------------------
 src/response/response.rs     |  2 +-
 3 files changed, 11 insertions(+), 50 deletions(-)

diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md
index 218ed5a6..c5e57e1a 100644
--- a/actix-http/CHANGES.md
+++ b/actix-http/CHANGES.md
@@ -1,6 +1,10 @@
 # Changes
 
 ## Unreleased - 2021-xx-xx
+### Removed
+* `header::map::GetAll` iterator, its `Iterator::size_hint` method was wrongly implemented. Replaced with `std::slice::Iter`. [#2527]
+
+[#2527]: https://github.com/actix/actix-web/pull/2527
 
 
 ## 3.0.0-beta.16 - 2021-12-17
diff --git a/actix-http/src/header/map.rs b/actix-http/src/header/map.rs
index 74841037..478867ed 100644
--- a/actix-http/src/header/map.rs
+++ b/actix-http/src/header/map.rs
@@ -306,8 +306,11 @@ impl HeaderMap {
     /// assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
     /// assert!(set_cookies_iter.next().is_none());
     /// ```
-    pub fn get_all(&self, key: impl AsHeaderName) -> GetAll<'_> {
-        GetAll::new(self.get_value(key))
+    pub fn get_all(&self, key: impl AsHeaderName) -> std::slice::Iter<'_, HeaderValue> {
+        match self.get_value(key) {
+            Some(value) => value.iter(),
+            None => (&[]).iter(),
+        }
     }
 
     // TODO: get_all_mut ?
@@ -602,52 +605,6 @@ impl<'a> IntoIterator for &'a HeaderMap {
     }
 }
 
-/// Iterator over borrowed values with the same associated name.
-///
-/// See [`HeaderMap::get_all`].
-#[derive(Debug)]
-pub struct GetAll<'a> {
-    idx: usize,
-    value: Option<&'a Value>,
-}
-
-impl<'a> GetAll<'a> {
-    fn new(value: Option<&'a Value>) -> Self {
-        Self { idx: 0, value }
-    }
-}
-
-impl<'a> Iterator for GetAll<'a> {
-    type Item = &'a HeaderValue;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let val = self.value?;
-
-        match val.get(self.idx) {
-            Some(val) => {
-                self.idx += 1;
-                Some(val)
-            }
-            None => {
-                // current index is none; remove value to fast-path future next calls
-                self.value = None;
-                None
-            }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        match self.value {
-            Some(val) => (val.len(), Some(val.len())),
-            None => (0, Some(0)),
-        }
-    }
-}
-
-impl ExactSizeIterator for GetAll<'_> {}
-
-impl iter::FusedIterator for GetAll<'_> {}
-
 /// Iterator over removed, owned values with the same associated name.
 ///
 /// Returned from methods that remove or replace items. See [`HeaderMap::insert`]
@@ -895,7 +852,7 @@ mod tests {
 
     assert_impl_all!(HeaderMap: IntoIterator);
     assert_impl_all!(Keys<'_>: Iterator, ExactSizeIterator, FusedIterator);
-    assert_impl_all!(GetAll<'_>: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(std::slice::Iter<'_, HeaderValue>: Iterator, ExactSizeIterator, FusedIterator);
     assert_impl_all!(Removed: Iterator, ExactSizeIterator, FusedIterator);
     assert_impl_all!(Iter<'_>: Iterator, ExactSizeIterator, FusedIterator);
     assert_impl_all!(IntoIter: Iterator, ExactSizeIterator, FusedIterator);
diff --git a/src/response/response.rs b/src/response/response.rs
index 4fb4b44b..6fa2082e 100644
--- a/src/response/response.rs
+++ b/src/response/response.rs
@@ -313,7 +313,7 @@ impl Future for HttpResponse<BoxBody> {
 
 #[cfg(feature = "cookies")]
 pub struct CookieIter<'a> {
-    iter: header::map::GetAll<'a>,
+    iter: std::slice::Iter<'a, HeaderValue>,
 }
 
 #[cfg(feature = "cookies")]