We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
IndexError when handle malformed  http response
I use urllib3 receive a http response like this,
```
HTTP/1.1 200 OK
	Content-Type: application/octet-stream
	Content-Length: 89606
	Content-Disposition: attachment; filename="MB-500Ap_2009-01-12.cfg"
	Connection: close

Brickcom-50xA
OperationSetting.locale=auto
HostName.name=cam
ModuleInfo.DIDO_module=1
ModuleInfo.PIR_module=0
ModuleInfo.WLED=0
SensorFPSSetting.fps=0
ModuleInfo.AUTOIRIS_module=0
ModuleInfo.IRCUT_module=0
ModuleInfo.IRLED_module=0
ModuleInfo.lightsensor=0
ModuleInfo.EXPOSURE_module=0
ModuleInfo.MDNS_module=0
ModuleInfo.PTZ_module=1
ModuleInfo.MSN_module=0
ModuleInfo.WIFI_module=0
ModuleInfo.watchDog_module=0
ModuleInfo.sdcard_module=1
ModuleInfo.usbstorage_module=0
ModuleInfo.sambamount_module=0
ModuleInfo.QoS=0
ModuleInfo.shutter_speed=0
ModuleInfo.discovery_internet=1
ModuleInfo.POE_module=
ModuleInfo.audio_record=1
```
it throws a IndexError,I print the traceback,
```
 req = http_get(url, auth=("admin", "admin"), timeout=timeout, verify=False)
  File "C:\Python27\lib\site-packages\requests\api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests\adapters.py", line 440, in send
    timeout=timeout
  File "C:\Python27\lib\site-packages\urllib3\connectionpool.py", line 617, in urlopen
    **response_kw)
  File "C:\Python27\lib\site-packages\urllib3\response.py", line 456, in from_httplib
    headers = HTTPHeaderDict.from_httplib(headers)
  File "C:\Python27\lib\site-packages\urllib3\_collections.py", line 312, in from_httplib
    key, value = headers[-1]
IndexError: list index out of range
```
how can I deal with this issue?

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

{"golden_diff": "diff --git a/urllib3/_collections.py b/urllib3/_collections.py\n--- a/urllib3/_collections.py\n+++ b/urllib3/_collections.py\n@@ -15,6 +15,7 @@\n     from collections import OrderedDict\n except ImportError:\n     from .packages.ordered_dict import OrderedDict\n+from .exceptions import InvalidHeader\n from .packages.six import iterkeys, itervalues, PY3\n \n \n@@ -305,13 +306,22 @@\n         # python2.7 does not expose a proper API for exporting multiheaders\n         # efficiently. This function re-reads raw lines from the message\n         # object and extracts the multiheaders properly.\n+        obs_fold_continued_leaders = (' ', '\\t')\n         headers = []\n \n         for line in message.headers:\n-            if line.startswith((' ', '\\t')):\n-                key, value = headers[-1]\n-                headers[-1] = (key, value + '\\r\\n' + line.rstrip())\n-                continue\n+            if line.startswith(obs_fold_continued_leaders):\n+                if not headers:\n+                    # We received a header line that starts with OWS as described\n+                    # in RFC-7230 S3.2.4. This indicates a multiline header, but\n+                    # there exists no previous header to which we can attach it.\n+                    raise InvalidHeader(\n+                        'Header continuation with no previous header: %s' % line\n+                    )\n+                else:\n+                    key, value = headers[-1]\n+                    headers[-1] = (key, value + ' ' + line.strip())\n+                    continue\n \n             key, value = line.split(':', 1)\n             headers.append((key, value.strip()))\n", "issue": "IndexError when handle malformed  http response\nI use urllib3 receive a http response like this,\r\n```\r\nHTTP/1.1 200 OK\r\n\tContent-Type: application/octet-stream\r\n\tContent-Length: 89606\r\n\tContent-Disposition: attachment; filename=\"MB-500Ap_2009-01-12.cfg\"\r\n\tConnection: close\r\n\r\nBrickcom-50xA\r\nOperationSetting.locale=auto\r\nHostName.name=cam\r\nModuleInfo.DIDO_module=1\r\nModuleInfo.PIR_module=0\r\nModuleInfo.WLED=0\r\nSensorFPSSetting.fps=0\r\nModuleInfo.AUTOIRIS_module=0\r\nModuleInfo.IRCUT_module=0\r\nModuleInfo.IRLED_module=0\r\nModuleInfo.lightsensor=0\r\nModuleInfo.EXPOSURE_module=0\r\nModuleInfo.MDNS_module=0\r\nModuleInfo.PTZ_module=1\r\nModuleInfo.MSN_module=0\r\nModuleInfo.WIFI_module=0\r\nModuleInfo.watchDog_module=0\r\nModuleInfo.sdcard_module=1\r\nModuleInfo.usbstorage_module=0\r\nModuleInfo.sambamount_module=0\r\nModuleInfo.QoS=0\r\nModuleInfo.shutter_speed=0\r\nModuleInfo.discovery_internet=1\r\nModuleInfo.POE_module=\r\nModuleInfo.audio_record=1\r\n```\r\nit throws a IndexError,I print the traceback,\r\n```\r\n req = http_get(url, auth=(\"admin\", \"admin\"), timeout=timeout, verify=False)\r\n  File \"C:\\Python27\\lib\\site-packages\\requests\\api.py\", line 72, in get\r\n    return request('get', url, params=params, **kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\requests\\api.py\", line 58, in request\r\n    return session.request(method=method, url=url, **kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\requests\\sessions.py\", line 508, in request\r\n    resp = self.send(prep, **send_kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\requests\\sessions.py\", line 618, in send\r\n    r = adapter.send(request, **kwargs)\r\n  File \"C:\\Python27\\lib\\site-packages\\requests\\adapters.py\", line 440, in send\r\n    timeout=timeout\r\n  File \"C:\\Python27\\lib\\site-packages\\urllib3\\connectionpool.py\", line 617, in urlopen\r\n    **response_kw)\r\n  File \"C:\\Python27\\lib\\site-packages\\urllib3\\response.py\", line 456, in from_httplib\r\n    headers = HTTPHeaderDict.from_httplib(headers)\r\n  File \"C:\\Python27\\lib\\site-packages\\urllib3\\_collections.py\", line 312, in from_httplib\r\n    key, value = headers[-1]\r\nIndexError: list index out of range\r\n```\r\nhow can I deal with this issue?\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom 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\nclass HTTPHeaderDict(MutableMapping):\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        super(HTTPHeaderDict, self).__init__()\n        self._container = OrderedDict()\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        self._container[key.lower()] = [key, val]\n        return self._container[key.lower()]\n\n    def __getitem__(self, key):\n        val = self._container[key.lower()]\n        return ', '.join(val[1:])\n\n    def __delitem__(self, key):\n        del self._container[key.lower()]\n\n    def __contains__(self, key):\n        return key.lower() in self._container\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((k.lower(), v) for k, v in self.itermerged()) ==\n                dict((k.lower(), v) for k, v in other.itermerged()))\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    if not PY3:  # Python 2\n        iterkeys = MutableMapping.iterkeys\n        itervalues = MutableMapping.itervalues\n\n    __marker = object()\n\n    def __len__(self):\n        return len(self._container)\n\n    def __iter__(self):\n        # Only provide the originally cased names\n        for vals in self._container.values():\n            yield vals[0]\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 = self._container.setdefault(key_lower, new_vals)\n        if new_vals is not vals:\n            vals.append(val)\n\n    def extend(self, *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) > 1:\n            raise TypeError(\"extend() takes at most 1 positional \"\n                            \"arguments ({0} given)\".format(len(args)))\n        other = args[0] if len(args) >= 1 else ()\n\n        if isinstance(other, HTTPHeaderDict):\n            for key, val in other.iteritems():\n                self.add(key, val)\n        elif 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, default=__marker):\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 = self._container[key.lower()]\n        except KeyError:\n            if default is self.__marker:\n                return []\n            return default\n        else:\n            return vals[1:]\n\n    # Backwards compatibility for httplib\n    getheaders = getlist\n    getallmatchingheaders = getlist\n    iget = getlist\n\n    # Backwards compatibility for http.cookiejar\n    get_all = 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 = other.getlist(key)\n            if isinstance(val, list):\n                # Don't need to convert tuples\n                val = list(val)\n            self._container[key.lower()] = [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 = self._container[key.lower()]\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 = self._container[key.lower()]\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):  # Python 2\n        \"\"\"Read headers from a Python 2 httplib message object.\"\"\"\n        # python2.7 does not expose a proper API for exporting multiheaders\n        # efficiently. This function re-reads raw lines from the message\n        # object and extracts the multiheaders properly.\n        headers = []\n\n        for line in message.headers:\n            if line.startswith((' ', '\\t')):\n                key, value = headers[-1]\n                headers[-1] = (key, value + '\\r\\n' + line.rstrip())\n                continue\n\n            key, value = line.split(':', 1)\n            headers.append((key, value.strip()))\n\n        return cls(headers)\n", "path": "urllib3/_collections.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom 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 .exceptions import InvalidHeader\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\nclass HTTPHeaderDict(MutableMapping):\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        super(HTTPHeaderDict, self).__init__()\n        self._container = OrderedDict()\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        self._container[key.lower()] = [key, val]\n        return self._container[key.lower()]\n\n    def __getitem__(self, key):\n        val = self._container[key.lower()]\n        return ', '.join(val[1:])\n\n    def __delitem__(self, key):\n        del self._container[key.lower()]\n\n    def __contains__(self, key):\n        return key.lower() in self._container\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((k.lower(), v) for k, v in self.itermerged()) ==\n                dict((k.lower(), v) for k, v in other.itermerged()))\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n    if not PY3:  # Python 2\n        iterkeys = MutableMapping.iterkeys\n        itervalues = MutableMapping.itervalues\n\n    __marker = object()\n\n    def __len__(self):\n        return len(self._container)\n\n    def __iter__(self):\n        # Only provide the originally cased names\n        for vals in self._container.values():\n            yield vals[0]\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 = self._container.setdefault(key_lower, new_vals)\n        if new_vals is not vals:\n            vals.append(val)\n\n    def extend(self, *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) > 1:\n            raise TypeError(\"extend() takes at most 1 positional \"\n                            \"arguments ({0} given)\".format(len(args)))\n        other = args[0] if len(args) >= 1 else ()\n\n        if isinstance(other, HTTPHeaderDict):\n            for key, val in other.iteritems():\n                self.add(key, val)\n        elif 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, default=__marker):\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 = self._container[key.lower()]\n        except KeyError:\n            if default is self.__marker:\n                return []\n            return default\n        else:\n            return vals[1:]\n\n    # Backwards compatibility for httplib\n    getheaders = getlist\n    getallmatchingheaders = getlist\n    iget = getlist\n\n    # Backwards compatibility for http.cookiejar\n    get_all = 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 = other.getlist(key)\n            if isinstance(val, list):\n                # Don't need to convert tuples\n                val = list(val)\n            self._container[key.lower()] = [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 = self._container[key.lower()]\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 = self._container[key.lower()]\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):  # Python 2\n        \"\"\"Read headers from a Python 2 httplib message object.\"\"\"\n        # python2.7 does not expose a proper API for exporting multiheaders\n        # efficiently. This function re-reads raw lines from the message\n        # object and extracts the multiheaders properly.\n        obs_fold_continued_leaders = (' ', '\\t')\n        headers = []\n\n        for line in message.headers:\n            if line.startswith(obs_fold_continued_leaders):\n                if not headers:\n                    # We received a header line that starts with OWS as described\n                    # in RFC-7230 S3.2.4. This indicates a multiline header, but\n                    # there exists no previous header to which we can attach it.\n                    raise InvalidHeader(\n                        'Header continuation with no previous header: %s' % line\n                    )\n                else:\n                    key, value = headers[-1]\n                    headers[-1] = (key, value + ' ' + line.strip())\n                    continue\n\n            key, value = line.split(':', 1)\n            headers.append((key, value.strip()))\n\n        return cls(headers)\n", "path": "urllib3/_collections.py"}]}