We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
duplicate/multiple headers are lost
When the server returns multiple headers of the same type, duplicated headers are lost. Example:

WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM

Results in only NTLM in the www-authenticate header.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `urllib3/_collections.py`
Content:
```
1 from collections import Mapping, MutableMapping
2 try:
3     from threading import RLock
4 except ImportError:  # Platform-specific: No threads available
5     class RLock:
6         def __enter__(self):
7             pass
8 
9         def __exit__(self, exc_type, exc_value, traceback):
10             pass
11 
12 
13 try:  # Python 2.7+
14     from collections import OrderedDict
15 except ImportError:
16     from .packages.ordered_dict import OrderedDict
17 from .packages.six import iterkeys, itervalues, PY3
18 
19 
20 __all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']
21 
22 
23 MULTIPLE_HEADERS_ALLOWED = frozenset(['cookie', 'set-cookie', 'set-cookie2'])
24 
25 _Null = object()
26 
27 
28 class RecentlyUsedContainer(MutableMapping):
29     """
30     Provides a thread-safe dict-like container which maintains up to
31     ``maxsize`` keys while throwing away the least-recently-used keys beyond
32     ``maxsize``.
33 
34     :param maxsize:
35         Maximum number of recent elements to retain.
36 
37     :param dispose_func:
38         Every time an item is evicted from the container,
39         ``dispose_func(value)`` is called.  Callback which will get called
40     """
41 
42     ContainerCls = OrderedDict
43 
44     def __init__(self, maxsize=10, dispose_func=None):
45         self._maxsize = maxsize
46         self.dispose_func = dispose_func
47 
48         self._container = self.ContainerCls()
49         self.lock = RLock()
50 
51     def __getitem__(self, key):
52         # Re-insert the item, moving it to the end of the eviction line.
53         with self.lock:
54             item = self._container.pop(key)
55             self._container[key] = item
56             return item
57 
58     def __setitem__(self, key, value):
59         evicted_value = _Null
60         with self.lock:
61             # Possibly evict the existing value of 'key'
62             evicted_value = self._container.get(key, _Null)
63             self._container[key] = value
64 
65             # If we didn't evict an existing value, we might have to evict the
66             # least recently used item from the beginning of the container.
67             if len(self._container) > self._maxsize:
68                 _key, evicted_value = self._container.popitem(last=False)
69 
70         if self.dispose_func and evicted_value is not _Null:
71             self.dispose_func(evicted_value)
72 
73     def __delitem__(self, key):
74         with self.lock:
75             value = self._container.pop(key)
76 
77         if self.dispose_func:
78             self.dispose_func(value)
79 
80     def __len__(self):
81         with self.lock:
82             return len(self._container)
83 
84     def __iter__(self):
85         raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')
86 
87     def clear(self):
88         with self.lock:
89             # Copy pointers to all values, then wipe the mapping
90             values = list(itervalues(self._container))
91             self._container.clear()
92 
93         if self.dispose_func:
94             for value in values:
95                 self.dispose_func(value)
96 
97     def keys(self):
98         with self.lock:
99             return list(iterkeys(self._container))
100 
101 
102 _dict_setitem = dict.__setitem__
103 _dict_getitem = dict.__getitem__
104 _dict_delitem = dict.__delitem__
105 _dict_contains = dict.__contains__
106 _dict_setdefault = dict.setdefault
107 
108 
109 class HTTPHeaderDict(dict):
110     """
111     :param headers:
112         An iterable of field-value pairs. Must not contain multiple field names
113         when compared case-insensitively.
114 
115     :param kwargs:
116         Additional field-value pairs to pass in to ``dict.update``.
117 
118     A ``dict`` like container for storing HTTP Headers.
119 
120     Field names are stored and compared case-insensitively in compliance with
121     RFC 7230. Iteration provides the first case-sensitive key seen for each
122     case-insensitive pair.
123 
124     Using ``__setitem__`` syntax overwrites fields that compare equal
125     case-insensitively in order to maintain ``dict``'s api. For fields that
126     compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
127     in a loop.
128 
129     If multiple fields that are equal case-insensitively are passed to the
130     constructor or ``.update``, the behavior is undefined and some will be
131     lost.
132 
133     >>> headers = HTTPHeaderDict()
134     >>> headers.add('Set-Cookie', 'foo=bar')
135     >>> headers.add('set-cookie', 'baz=quxx')
136     >>> headers['content-length'] = '7'
137     >>> headers['SET-cookie']
138     'foo=bar, baz=quxx'
139     >>> headers['Content-Length']
140     '7'
141     """
142 
143     def __init__(self, headers=None, **kwargs):
144         dict.__init__(self)
145         if headers is not None:
146             self.extend(headers)
147         if kwargs:
148             self.extend(kwargs)
149 
150     def __setitem__(self, key, val):
151         return _dict_setitem(self, key.lower(), (key, val))
152 
153     def __getitem__(self, key):
154         val = _dict_getitem(self, key.lower())
155         return ', '.join(val[1:])
156 
157     def __delitem__(self, key):
158         return _dict_delitem(self, key.lower())
159 
160     def __contains__(self, key):
161         return _dict_contains(self, key.lower())
162 
163     def __eq__(self, other):
164         if not isinstance(other, Mapping) and not hasattr(other, 'keys'):
165             return False
166         if not isinstance(other, type(self)):
167             other = type(self)(other)
168         return dict((k1, self[k1]) for k1 in self) == dict((k2, other[k2]) for k2 in other)
169 
170     def __ne__(self, other):
171         return not self.__eq__(other)
172 
173     values = MutableMapping.values
174     get = MutableMapping.get
175     update = MutableMapping.update
176     
177     if not PY3: # Python 2
178         iterkeys = MutableMapping.iterkeys
179         itervalues = MutableMapping.itervalues
180 
181     __marker = object()
182 
183     def pop(self, key, default=__marker):
184         '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
185           If key is not found, d is returned if given, otherwise KeyError is raised.
186         '''
187         # Using the MutableMapping function directly fails due to the private marker.
188         # Using ordinary dict.pop would expose the internal structures.
189         # So let's reinvent the wheel.
190         try:
191             value = self[key]
192         except KeyError:
193             if default is self.__marker:
194                 raise
195             return default
196         else:
197             del self[key]
198             return value
199 
200     def discard(self, key):
201         try:
202             del self[key]
203         except KeyError:
204             pass
205 
206     def add(self, key, val):
207         """Adds a (name, value) pair, doesn't overwrite the value if it already
208         exists.
209 
210         >>> headers = HTTPHeaderDict(foo='bar')
211         >>> headers.add('Foo', 'baz')
212         >>> headers['foo']
213         'bar, baz'
214         """
215         key_lower = key.lower()
216         new_vals = key, val
217         # Keep the common case aka no item present as fast as possible
218         vals = _dict_setdefault(self, key_lower, new_vals)
219         if new_vals is not vals:
220             # new_vals was not inserted, as there was a previous one
221             if isinstance(vals, list):
222                 # If already several items got inserted, we have a list
223                 vals.append(val)
224             else:
225                 # vals should be a tuple then, i.e. only one item so far
226                 if key_lower in MULTIPLE_HEADERS_ALLOWED:
227                     # Need to convert the tuple to list for further extension
228                     _dict_setitem(self, key_lower, [vals[0], vals[1], val])
229                 else:
230                     _dict_setitem(self, key_lower, new_vals)
231 
232     def extend(*args, **kwargs):
233         """Generic import function for any type of header-like object.
234         Adapted version of MutableMapping.update in order to insert items
235         with self.add instead of self.__setitem__
236         """
237         if len(args) > 2:
238             raise TypeError("update() takes at most 2 positional "
239                             "arguments ({} given)".format(len(args)))
240         elif not args:
241             raise TypeError("update() takes at least 1 argument (0 given)")
242         self = args[0]
243         other = args[1] if len(args) >= 2 else ()
244         
245         if isinstance(other, Mapping):
246             for key in other:
247                 self.add(key, other[key])
248         elif hasattr(other, "keys"):
249             for key in other.keys():
250                 self.add(key, other[key])
251         else:
252             for key, value in other:
253                 self.add(key, value)
254 
255         for key, value in kwargs.items():
256             self.add(key, value)
257 
258     def getlist(self, key):
259         """Returns a list of all the values for the named field. Returns an
260         empty list if the key doesn't exist."""
261         try:
262             vals = _dict_getitem(self, key.lower())
263         except KeyError:
264             return []
265         else:
266             if isinstance(vals, tuple):
267                 return [vals[1]]
268             else:
269                 return vals[1:]
270 
271     # Backwards compatibility for httplib
272     getheaders = getlist
273     getallmatchingheaders = getlist
274     iget = getlist
275 
276     def __repr__(self):
277         return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
278 
279     def copy(self):
280         clone = type(self)()
281         for key in self:
282             val = _dict_getitem(self, key)
283             if isinstance(val, list):
284                 # Don't need to convert tuples
285                 val = list(val)
286             _dict_setitem(clone, key, val)
287         return clone
288 
289     def iteritems(self):
290         """Iterate over all header lines, including duplicate ones."""
291         for key in self:
292             vals = _dict_getitem(self, key)
293             for val in vals[1:]:
294                 yield vals[0], val
295 
296     def itermerged(self):
297         """Iterate over all headers, merging duplicate ones together."""
298         for key in self:
299             val = _dict_getitem(self, key)
300             yield val[0], ', '.join(val[1:])
301 
302     def items(self):
303         return list(self.iteritems())
304 
305     @classmethod
306     def from_httplib(cls, message, duplicates=('set-cookie',)): # Python 2
307         """Read headers from a Python 2 httplib message object."""
308         ret = cls(message.items())
309         # ret now contains only the last header line for each duplicate.
310         # Importing with all duplicates would be nice, but this would
311         # mean to repeat most of the raw parsing already done, when the
312         # message object was created. Extracting only the headers of interest 
313         # separately, the cookies, should be faster and requires less
314         # extra code.
315         for key in duplicates:
316             ret.discard(key)
317             for val in message.getheaders(key):
318                 ret.add(key, val)
319             return ret
320
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/urllib3/_collections.py b/urllib3/_collections.py
--- a/urllib3/_collections.py
+++ b/urllib3/_collections.py
@@ -20,8 +20,6 @@
 __all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']
 
 
-MULTIPLE_HEADERS_ALLOWED = frozenset(['cookie', 'set-cookie', 'set-cookie2'])
-
 _Null = object()
 
 
@@ -143,7 +141,10 @@
     def __init__(self, headers=None, **kwargs):
         dict.__init__(self)
         if headers is not None:
-            self.extend(headers)
+            if isinstance(headers, HTTPHeaderDict):
+                self._copy_from(headers)
+            else:
+                self.extend(headers)
         if kwargs:
             self.extend(kwargs)
 
@@ -223,11 +224,8 @@
                 vals.append(val)
             else:
                 # vals should be a tuple then, i.e. only one item so far
-                if key_lower in MULTIPLE_HEADERS_ALLOWED:
-                    # Need to convert the tuple to list for further extension
-                    _dict_setitem(self, key_lower, [vals[0], vals[1], val])
-                else:
-                    _dict_setitem(self, key_lower, new_vals)
+                # Need to convert the tuple to list for further extension
+                _dict_setitem(self, key_lower, [vals[0], vals[1], val])
 
     def extend(*args, **kwargs):
         """Generic import function for any type of header-like object.
@@ -276,14 +274,17 @@
     def __repr__(self):
         return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
 
-    def copy(self):
-        clone = type(self)()
-        for key in self:
-            val = _dict_getitem(self, key)
+    def _copy_from(self, other):
+        for key in other:
+            val = _dict_getitem(other, key)
             if isinstance(val, list):
                 # Don't need to convert tuples
                 val = list(val)
-            _dict_setitem(clone, key, val)
+            _dict_setitem(self, key, val)
+
+    def copy(self):
+        clone = type(self)()
+        clone._copy_from(self)
         return clone
 
     def iteritems(self):

{"golden_diff": "diff --git a/urllib3/_collections.py b/urllib3/_collections.py\n--- a/urllib3/_collections.py\n+++ b/urllib3/_collections.py\n@@ -20,8 +20,6 @@\n __all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']\n \n \n-MULTIPLE_HEADERS_ALLOWED = frozenset(['cookie', 'set-cookie', 'set-cookie2'])\n-\n _Null = object()\n \n \n@@ -143,7 +141,10 @@\n     def __init__(self, headers=None, **kwargs):\n         dict.__init__(self)\n         if headers is not None:\n-            self.extend(headers)\n+            if isinstance(headers, HTTPHeaderDict):\n+                self._copy_from(headers)\n+            else:\n+                self.extend(headers)\n         if kwargs:\n             self.extend(kwargs)\n \n@@ -223,11 +224,8 @@\n                 vals.append(val)\n             else:\n                 # vals should be a tuple then, i.e. only one item so far\n-                if key_lower in MULTIPLE_HEADERS_ALLOWED:\n-                    # Need to convert the tuple to list for further extension\n-                    _dict_setitem(self, key_lower, [vals[0], vals[1], val])\n-                else:\n-                    _dict_setitem(self, key_lower, new_vals)\n+                # Need to convert the tuple to list for further extension\n+                _dict_setitem(self, key_lower, [vals[0], vals[1], val])\n \n     def extend(*args, **kwargs):\n         \"\"\"Generic import function for any type of header-like object.\n@@ -276,14 +274,17 @@\n     def __repr__(self):\n         return \"%s(%s)\" % (type(self).__name__, dict(self.itermerged()))\n \n-    def copy(self):\n-        clone = type(self)()\n-        for key in self:\n-            val = _dict_getitem(self, key)\n+    def _copy_from(self, other):\n+        for key in other:\n+            val = _dict_getitem(other, key)\n             if isinstance(val, list):\n                 # Don't need to convert tuples\n                 val = list(val)\n-            _dict_setitem(clone, key, val)\n+            _dict_setitem(self, key, val)\n+\n+    def copy(self):\n+        clone = type(self)()\n+        clone._copy_from(self)\n         return clone\n \n     def iteritems(self):\n", "issue": "duplicate/multiple headers are lost\nWhen the server returns multiple headers of the same type, duplicated headers are lost. Example:\n\nWWW-Authenticate: Negotiate\nWWW-Authenticate: NTLM\n\nResults in only NTLM in the www-authenticate header.\n\n", "before_files": [{"content": "from collections import Mapping, MutableMapping\ntry:\n    from threading import RLock\nexcept ImportError:  # Platform-specific: No threads available\n    class RLock:\n        def __enter__(self):\n            pass\n\n        def __exit__(self, exc_type, exc_value, traceback):\n            pass\n\n\ntry:  # Python 2.7+\n    from collections import OrderedDict\nexcept ImportError:\n    from .packages.ordered_dict import OrderedDict\nfrom .packages.six import iterkeys, itervalues, PY3\n\n\n__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']\n\n\nMULTIPLE_HEADERS_ALLOWED = frozenset(['cookie', 'set-cookie', 'set-cookie2'])\n\n_Null = object()\n\n\nclass RecentlyUsedContainer(MutableMapping):\n    \"\"\"\n    Provides a thread-safe dict-like container which maintains up to\n    ``maxsize`` keys while throwing away the least-recently-used keys beyond\n    ``maxsize``.\n\n    :param maxsize:\n        Maximum number of recent elements to retain.\n\n    :param dispose_func:\n        Every time an item is evicted from the container,\n        ``dispose_func(value)`` is called.  Callback which will get called\n    \"\"\"\n\n    ContainerCls = OrderedDict\n\n    def __init__(self, maxsize=10, dispose_func=None):\n        self._maxsize = maxsize\n        self.dispose_func = dispose_func\n\n        self._container = self.ContainerCls()\n        self.lock = RLock()\n\n    def __getitem__(self, key):\n        # Re-insert the item, moving it to the end of the eviction line.\n        with self.lock:\n            item = self._container.pop(key)\n            self._container[key] = item\n            return item\n\n    def __setitem__(self, key, value):\n        evicted_value = _Null\n        with self.lock:\n            # Possibly evict the existing value of 'key'\n            evicted_value = self._container.get(key, _Null)\n            self._container[key] = value\n\n            # If we didn't evict an existing value, we might have to evict the\n            # least recently used item from the beginning of the container.\n            if len(self._container) > self._maxsize:\n                _key, evicted_value = self._container.popitem(last=False)\n\n        if self.dispose_func and evicted_value is not _Null:\n            self.dispose_func(evicted_value)\n\n    def __delitem__(self, key):\n        with self.lock:\n            value = self._container.pop(key)\n\n        if self.dispose_func:\n            self.dispose_func(value)\n\n    def __len__(self):\n        with self.lock:\n            return len(self._container)\n\n    def __iter__(self):\n        raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')\n\n    def clear(self):\n        with self.lock:\n            # Copy pointers to all values, then wipe the mapping\n            values = list(itervalues(self._container))\n            self._container.clear()\n\n        if self.dispose_func:\n            for value in values:\n                self.dispose_func(value)\n\n    def keys(self):\n        with self.lock:\n            return list(iterkeys(self._container))\n\n\n_dict_setitem = dict.__setitem__\n_dict_getitem = dict.__getitem__\n_dict_delitem = dict.__delitem__\n_dict_contains = dict.__contains__\n_dict_setdefault = dict.setdefault\n\n\nclass HTTPHeaderDict(dict):\n    \"\"\"\n    :param headers:\n        An iterable of field-value pairs. Must not contain multiple field names\n        when compared case-insensitively.\n\n    :param kwargs:\n        Additional field-value pairs to pass in to ``dict.update``.\n\n    A ``dict`` like container for storing HTTP Headers.\n\n    Field names are stored and compared case-insensitively in compliance with\n    RFC 7230. Iteration provides the first case-sensitive key seen for each\n    case-insensitive pair.\n\n    Using ``__setitem__`` syntax overwrites fields that compare equal\n    case-insensitively in order to maintain ``dict``'s api. For fields that\n    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``\n    in a loop.\n\n    If multiple fields that are equal case-insensitively are passed to the\n    constructor or ``.update``, the behavior is undefined and some will be\n    lost.\n\n    >>> headers = HTTPHeaderDict()\n    >>> headers.add('Set-Cookie', 'foo=bar')\n    >>> headers.add('set-cookie', 'baz=quxx')\n    >>> headers['content-length'] = '7'\n    >>> headers['SET-cookie']\n    'foo=bar, baz=quxx'\n    >>> headers['Content-Length']\n    '7'\n    \"\"\"\n\n    def __init__(self, headers=None, **kwargs):\n        dict.__init__(self)\n        if headers is not None:\n            self.extend(headers)\n        if kwargs:\n            self.extend(kwargs)\n\n    def __setitem__(self, key, val):\n        return _dict_setitem(self, key.lower(), (key, val))\n\n    def __getitem__(self, key):\n        val = _dict_getitem(self, key.lower())\n        return ', '.join(val[1:])\n\n    def __delitem__(self, key):\n        return _dict_delitem(self, key.lower())\n\n    def __contains__(self, key):\n        return _dict_contains(self, key.lower())\n\n    def __eq__(self, other):\n        if not isinstance(other, Mapping) and not hasattr(other, 'keys'):\n            return False\n        if not isinstance(other, type(self)):\n            other = type(self)(other)\n        return dict((k1, self[k1]) for k1 in self) == dict((k2, other[k2]) for k2 in other)\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    values = MutableMapping.values\n    get = MutableMapping.get\n    update = MutableMapping.update\n    \n    if not PY3: # Python 2\n        iterkeys = MutableMapping.iterkeys\n        itervalues = MutableMapping.itervalues\n\n    __marker = object()\n\n    def pop(self, key, default=__marker):\n        '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n          If key is not found, d is returned if given, otherwise KeyError is raised.\n        '''\n        # Using the MutableMapping function directly fails due to the private marker.\n        # Using ordinary dict.pop would expose the internal structures.\n        # So let's reinvent the wheel.\n        try:\n            value = self[key]\n        except KeyError:\n            if default is self.__marker:\n                raise\n            return default\n        else:\n            del self[key]\n            return value\n\n    def discard(self, key):\n        try:\n            del self[key]\n        except KeyError:\n            pass\n\n    def add(self, key, val):\n        \"\"\"Adds a (name, value) pair, doesn't overwrite the value if it already\n        exists.\n\n        >>> headers = HTTPHeaderDict(foo='bar')\n        >>> headers.add('Foo', 'baz')\n        >>> headers['foo']\n        'bar, baz'\n        \"\"\"\n        key_lower = key.lower()\n        new_vals = key, val\n        # Keep the common case aka no item present as fast as possible\n        vals = _dict_setdefault(self, key_lower, new_vals)\n        if new_vals is not vals:\n            # new_vals was not inserted, as there was a previous one\n            if isinstance(vals, list):\n                # If already several items got inserted, we have a list\n                vals.append(val)\n            else:\n                # vals should be a tuple then, i.e. only one item so far\n                if key_lower in MULTIPLE_HEADERS_ALLOWED:\n                    # Need to convert the tuple to list for further extension\n                    _dict_setitem(self, key_lower, [vals[0], vals[1], val])\n                else:\n                    _dict_setitem(self, key_lower, new_vals)\n\n    def extend(*args, **kwargs):\n        \"\"\"Generic import function for any type of header-like object.\n        Adapted version of MutableMapping.update in order to insert items\n        with self.add instead of self.__setitem__\n        \"\"\"\n        if len(args) > 2:\n            raise TypeError(\"update() takes at most 2 positional \"\n                            \"arguments ({} given)\".format(len(args)))\n        elif not args:\n            raise TypeError(\"update() takes at least 1 argument (0 given)\")\n        self = args[0]\n        other = args[1] if len(args) >= 2 else ()\n        \n        if isinstance(other, Mapping):\n            for key in other:\n                self.add(key, other[key])\n        elif hasattr(other, \"keys\"):\n            for key in other.keys():\n                self.add(key, other[key])\n        else:\n            for key, value in other:\n                self.add(key, value)\n\n        for key, value in kwargs.items():\n            self.add(key, value)\n\n    def getlist(self, key):\n        \"\"\"Returns a list of all the values for the named field. Returns an\n        empty list if the key doesn't exist.\"\"\"\n        try:\n            vals = _dict_getitem(self, key.lower())\n        except KeyError:\n            return []\n        else:\n            if isinstance(vals, tuple):\n                return [vals[1]]\n            else:\n                return vals[1:]\n\n    # Backwards compatibility for httplib\n    getheaders = getlist\n    getallmatchingheaders = getlist\n    iget = getlist\n\n    def __repr__(self):\n        return \"%s(%s)\" % (type(self).__name__, dict(self.itermerged()))\n\n    def copy(self):\n        clone = type(self)()\n        for key in self:\n            val = _dict_getitem(self, key)\n            if isinstance(val, list):\n                # Don't need to convert tuples\n                val = list(val)\n            _dict_setitem(clone, key, val)\n        return clone\n\n    def iteritems(self):\n        \"\"\"Iterate over all header lines, including duplicate ones.\"\"\"\n        for key in self:\n            vals = _dict_getitem(self, key)\n            for val in vals[1:]:\n                yield vals[0], val\n\n    def itermerged(self):\n        \"\"\"Iterate over all headers, merging duplicate ones together.\"\"\"\n        for key in self:\n            val = _dict_getitem(self, key)\n            yield val[0], ', '.join(val[1:])\n\n    def items(self):\n        return list(self.iteritems())\n\n    @classmethod\n    def from_httplib(cls, message, duplicates=('set-cookie',)): # Python 2\n        \"\"\"Read headers from a Python 2 httplib message object.\"\"\"\n        ret = cls(message.items())\n        # ret now contains only the last header line for each duplicate.\n        # Importing with all duplicates would be nice, but this would\n        # mean to repeat most of the raw parsing already done, when the\n        # message object was created. Extracting only the headers of interest \n        # separately, the cookies, should be faster and requires less\n        # extra code.\n        for key in duplicates:\n            ret.discard(key)\n            for val in message.getheaders(key):\n                ret.add(key, val)\n            return ret\n", "path": "urllib3/_collections.py"}], "after_files": [{"content": "from collections import Mapping, MutableMapping\ntry:\n    from threading import RLock\nexcept ImportError:  # Platform-specific: No threads available\n    class RLock:\n        def __enter__(self):\n            pass\n\n        def __exit__(self, exc_type, exc_value, traceback):\n            pass\n\n\ntry:  # Python 2.7+\n    from collections import OrderedDict\nexcept ImportError:\n    from .packages.ordered_dict import OrderedDict\nfrom .packages.six import iterkeys, itervalues, PY3\n\n\n__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict']\n\n\n_Null = object()\n\n\nclass RecentlyUsedContainer(MutableMapping):\n    \"\"\"\n    Provides a thread-safe dict-like container which maintains up to\n    ``maxsize`` keys while throwing away the least-recently-used keys beyond\n    ``maxsize``.\n\n    :param maxsize:\n        Maximum number of recent elements to retain.\n\n    :param dispose_func:\n        Every time an item is evicted from the container,\n        ``dispose_func(value)`` is called.  Callback which will get called\n    \"\"\"\n\n    ContainerCls = OrderedDict\n\n    def __init__(self, maxsize=10, dispose_func=None):\n        self._maxsize = maxsize\n        self.dispose_func = dispose_func\n\n        self._container = self.ContainerCls()\n        self.lock = RLock()\n\n    def __getitem__(self, key):\n        # Re-insert the item, moving it to the end of the eviction line.\n        with self.lock:\n            item = self._container.pop(key)\n            self._container[key] = item\n            return item\n\n    def __setitem__(self, key, value):\n        evicted_value = _Null\n        with self.lock:\n            # Possibly evict the existing value of 'key'\n            evicted_value = self._container.get(key, _Null)\n            self._container[key] = value\n\n            # If we didn't evict an existing value, we might have to evict the\n            # least recently used item from the beginning of the container.\n            if len(self._container) > self._maxsize:\n                _key, evicted_value = self._container.popitem(last=False)\n\n        if self.dispose_func and evicted_value is not _Null:\n            self.dispose_func(evicted_value)\n\n    def __delitem__(self, key):\n        with self.lock:\n            value = self._container.pop(key)\n\n        if self.dispose_func:\n            self.dispose_func(value)\n\n    def __len__(self):\n        with self.lock:\n            return len(self._container)\n\n    def __iter__(self):\n        raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.')\n\n    def clear(self):\n        with self.lock:\n            # Copy pointers to all values, then wipe the mapping\n            values = list(itervalues(self._container))\n            self._container.clear()\n\n        if self.dispose_func:\n            for value in values:\n                self.dispose_func(value)\n\n    def keys(self):\n        with self.lock:\n            return list(iterkeys(self._container))\n\n\n_dict_setitem = dict.__setitem__\n_dict_getitem = dict.__getitem__\n_dict_delitem = dict.__delitem__\n_dict_contains = dict.__contains__\n_dict_setdefault = dict.setdefault\n\n\nclass HTTPHeaderDict(dict):\n    \"\"\"\n    :param headers:\n        An iterable of field-value pairs. Must not contain multiple field names\n        when compared case-insensitively.\n\n    :param kwargs:\n        Additional field-value pairs to pass in to ``dict.update``.\n\n    A ``dict`` like container for storing HTTP Headers.\n\n    Field names are stored and compared case-insensitively in compliance with\n    RFC 7230. Iteration provides the first case-sensitive key seen for each\n    case-insensitive pair.\n\n    Using ``__setitem__`` syntax overwrites fields that compare equal\n    case-insensitively in order to maintain ``dict``'s api. For fields that\n    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``\n    in a loop.\n\n    If multiple fields that are equal case-insensitively are passed to the\n    constructor or ``.update``, the behavior is undefined and some will be\n    lost.\n\n    >>> headers = HTTPHeaderDict()\n    >>> headers.add('Set-Cookie', 'foo=bar')\n    >>> headers.add('set-cookie', 'baz=quxx')\n    >>> headers['content-length'] = '7'\n    >>> headers['SET-cookie']\n    'foo=bar, baz=quxx'\n    >>> headers['Content-Length']\n    '7'\n    \"\"\"\n\n    def __init__(self, headers=None, **kwargs):\n        dict.__init__(self)\n        if headers is not None:\n            if isinstance(headers, HTTPHeaderDict):\n                self._copy_from(headers)\n            else:\n                self.extend(headers)\n        if kwargs:\n            self.extend(kwargs)\n\n    def __setitem__(self, key, val):\n        return _dict_setitem(self, key.lower(), (key, val))\n\n    def __getitem__(self, key):\n        val = _dict_getitem(self, key.lower())\n        return ', '.join(val[1:])\n\n    def __delitem__(self, key):\n        return _dict_delitem(self, key.lower())\n\n    def __contains__(self, key):\n        return _dict_contains(self, key.lower())\n\n    def __eq__(self, other):\n        if not isinstance(other, Mapping) and not hasattr(other, 'keys'):\n            return False\n        if not isinstance(other, type(self)):\n            other = type(self)(other)\n        return dict((k1, self[k1]) for k1 in self) == dict((k2, other[k2]) for k2 in other)\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    values = MutableMapping.values\n    get = MutableMapping.get\n    update = MutableMapping.update\n    \n    if not PY3: # Python 2\n        iterkeys = MutableMapping.iterkeys\n        itervalues = MutableMapping.itervalues\n\n    __marker = object()\n\n    def pop(self, key, default=__marker):\n        '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n          If key is not found, d is returned if given, otherwise KeyError is raised.\n        '''\n        # Using the MutableMapping function directly fails due to the private marker.\n        # Using ordinary dict.pop would expose the internal structures.\n        # So let's reinvent the wheel.\n        try:\n            value = self[key]\n        except KeyError:\n            if default is self.__marker:\n                raise\n            return default\n        else:\n            del self[key]\n            return value\n\n    def discard(self, key):\n        try:\n            del self[key]\n        except KeyError:\n            pass\n\n    def add(self, key, val):\n        \"\"\"Adds a (name, value) pair, doesn't overwrite the value if it already\n        exists.\n\n        >>> headers = HTTPHeaderDict(foo='bar')\n        >>> headers.add('Foo', 'baz')\n        >>> headers['foo']\n        'bar, baz'\n        \"\"\"\n        key_lower = key.lower()\n        new_vals = key, val\n        # Keep the common case aka no item present as fast as possible\n        vals = _dict_setdefault(self, key_lower, new_vals)\n        if new_vals is not vals:\n            # new_vals was not inserted, as there was a previous one\n            if isinstance(vals, list):\n                # If already several items got inserted, we have a list\n                vals.append(val)\n            else:\n                # vals should be a tuple then, i.e. only one item so far\n                # Need to convert the tuple to list for further extension\n                _dict_setitem(self, key_lower, [vals[0], vals[1], val])\n\n    def extend(*args, **kwargs):\n        \"\"\"Generic import function for any type of header-like object.\n        Adapted version of MutableMapping.update in order to insert items\n        with self.add instead of self.__setitem__\n        \"\"\"\n        if len(args) > 2:\n            raise TypeError(\"update() takes at most 2 positional \"\n                            \"arguments ({} given)\".format(len(args)))\n        elif not args:\n            raise TypeError(\"update() takes at least 1 argument (0 given)\")\n        self = args[0]\n        other = args[1] if len(args) >= 2 else ()\n        \n        if isinstance(other, Mapping):\n            for key in other:\n                self.add(key, other[key])\n        elif hasattr(other, \"keys\"):\n            for key in other.keys():\n                self.add(key, other[key])\n        else:\n            for key, value in other:\n                self.add(key, value)\n\n        for key, value in kwargs.items():\n            self.add(key, value)\n\n    def getlist(self, key):\n        \"\"\"Returns a list of all the values for the named field. Returns an\n        empty list if the key doesn't exist.\"\"\"\n        try:\n            vals = _dict_getitem(self, key.lower())\n        except KeyError:\n            return []\n        else:\n            if isinstance(vals, tuple):\n                return [vals[1]]\n            else:\n                return vals[1:]\n\n    # Backwards compatibility for httplib\n    getheaders = getlist\n    getallmatchingheaders = getlist\n    iget = getlist\n\n    def __repr__(self):\n        return \"%s(%s)\" % (type(self).__name__, dict(self.itermerged()))\n\n    def _copy_from(self, other):\n        for key in other:\n            val = _dict_getitem(other, key)\n            if isinstance(val, list):\n                # Don't need to convert tuples\n                val = list(val)\n            _dict_setitem(self, key, val)\n\n    def copy(self):\n        clone = type(self)()\n        clone._copy_from(self)\n        return clone\n\n    def iteritems(self):\n        \"\"\"Iterate over all header lines, including duplicate ones.\"\"\"\n        for key in self:\n            vals = _dict_getitem(self, key)\n            for val in vals[1:]:\n                yield vals[0], val\n\n    def itermerged(self):\n        \"\"\"Iterate over all headers, merging duplicate ones together.\"\"\"\n        for key in self:\n            val = _dict_getitem(self, key)\n            yield val[0], ', '.join(val[1:])\n\n    def items(self):\n        return list(self.iteritems())\n\n    @classmethod\n    def from_httplib(cls, message, duplicates=('set-cookie',)): # Python 2\n        \"\"\"Read headers from a Python 2 httplib message object.\"\"\"\n        ret = cls(message.items())\n        # ret now contains only the last header line for each duplicate.\n        # Importing with all duplicates would be nice, but this would\n        # mean to repeat most of the raw parsing already done, when the\n        # message object was created. Extracting only the headers of interest \n        # separately, the cookies, should be faster and requires less\n        # extra code.\n        for key in duplicates:\n            ret.discard(key)\n            for val in message.getheaders(key):\n                ret.add(key, val)\n            return ret\n", "path": "urllib3/_collections.py"}]}