We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add documentation for HTTPResponse `io` support
Reminder for @eteq re #187:

> Would you be up for adding a bit to the documentation/comments which talks about the use cases or benefits of this? That would be greatly appreciated. :)


--- 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/response.py`
Content:
```
1 import zlib
2 import io
3 from socket import timeout as SocketTimeout
4 
5 from ._collections import HTTPHeaderDict
6 from .exceptions import ProtocolError, DecodeError, ReadTimeoutError
7 from .packages.six import string_types as basestring, binary_type
8 from .connection import HTTPException, BaseSSLError
9 from .util.response import is_fp_closed
10 
11 
12 
13 class DeflateDecoder(object):
14 
15     def __init__(self):
16         self._first_try = True
17         self._data = binary_type()
18         self._obj = zlib.decompressobj()
19 
20     def __getattr__(self, name):
21         return getattr(self._obj, name)
22 
23     def decompress(self, data):
24         if not self._first_try:
25             return self._obj.decompress(data)
26 
27         self._data += data
28         try:
29             return self._obj.decompress(data)
30         except zlib.error:
31             self._first_try = False
32             self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
33             try:
34                 return self.decompress(self._data)
35             finally:
36                 self._data = None
37 
38 
39 def _get_decoder(mode):
40     if mode == 'gzip':
41         return zlib.decompressobj(16 + zlib.MAX_WBITS)
42 
43     return DeflateDecoder()
44 
45 
46 class HTTPResponse(io.IOBase):
47     """
48     HTTP Response container.
49 
50     Backwards-compatible to httplib's HTTPResponse but the response ``body`` is
51     loaded and decoded on-demand when the ``data`` property is accessed.
52 
53     Extra parameters for behaviour not present in httplib.HTTPResponse:
54 
55     :param preload_content:
56         If True, the response's body will be preloaded during construction.
57 
58     :param decode_content:
59         If True, attempts to decode specific content-encoding's based on headers
60         (like 'gzip' and 'deflate') will be skipped and raw data will be used
61         instead.
62 
63     :param original_response:
64         When this HTTPResponse wrapper is generated from an httplib.HTTPResponse
65         object, it's convenient to include the original for debug purposes. It's
66         otherwise unused.
67     """
68 
69     CONTENT_DECODERS = ['gzip', 'deflate']
70     REDIRECT_STATUSES = [301, 302, 303, 307, 308]
71 
72     def __init__(self, body='', headers=None, status=0, version=0, reason=None,
73                  strict=0, preload_content=True, decode_content=True,
74                  original_response=None, pool=None, connection=None):
75 
76         self.headers = HTTPHeaderDict()
77         if headers:
78             self.headers.update(headers)
79         self.status = status
80         self.version = version
81         self.reason = reason
82         self.strict = strict
83         self.decode_content = decode_content
84 
85         self._decoder = None
86         self._body = None
87         self._fp = None
88         self._original_response = original_response
89         self._fp_bytes_read = 0
90 
91         if body and isinstance(body, (basestring, binary_type)):
92             self._body = body
93 
94         self._pool = pool
95         self._connection = connection
96 
97         if hasattr(body, 'read'):
98             self._fp = body
99 
100         if preload_content and not self._body:
101             self._body = self.read(decode_content=decode_content)
102 
103     def get_redirect_location(self):
104         """
105         Should we redirect and where to?
106 
107         :returns: Truthy redirect location string if we got a redirect status
108             code and valid location. ``None`` if redirect status and no
109             location. ``False`` if not a redirect status code.
110         """
111         if self.status in self.REDIRECT_STATUSES:
112             return self.headers.get('location')
113 
114         return False
115 
116     def release_conn(self):
117         if not self._pool or not self._connection:
118             return
119 
120         self._pool._put_conn(self._connection)
121         self._connection = None
122 
123     @property
124     def data(self):
125         # For backwords-compat with earlier urllib3 0.4 and earlier.
126         if self._body:
127             return self._body
128 
129         if self._fp:
130             return self.read(cache_content=True)
131 
132     def tell(self):
133         """
134         Obtain the number of bytes pulled over the wire so far. May differ from
135         the amount of content returned by :meth:``HTTPResponse.read`` if bytes
136         are encoded on the wire (e.g, compressed).
137         """
138         return self._fp_bytes_read
139 
140     def read(self, amt=None, decode_content=None, cache_content=False):
141         """
142         Similar to :meth:`httplib.HTTPResponse.read`, but with two additional
143         parameters: ``decode_content`` and ``cache_content``.
144 
145         :param amt:
146             How much of the content to read. If specified, caching is skipped
147             because it doesn't make sense to cache partial content as the full
148             response.
149 
150         :param decode_content:
151             If True, will attempt to decode the body based on the
152             'content-encoding' header.
153 
154         :param cache_content:
155             If True, will save the returned data such that the same result is
156             returned despite of the state of the underlying file object. This
157             is useful if you want the ``.data`` property to continue working
158             after having ``.read()`` the file object. (Overridden if ``amt`` is
159             set.)
160         """
161         # Note: content-encoding value should be case-insensitive, per RFC 7230
162         # Section 3.2
163         content_encoding = self.headers.get('content-encoding', '').lower()
164         if self._decoder is None:
165             if content_encoding in self.CONTENT_DECODERS:
166                 self._decoder = _get_decoder(content_encoding)
167         if decode_content is None:
168             decode_content = self.decode_content
169 
170         if self._fp is None:
171             return
172 
173         flush_decoder = False
174 
175         try:
176             try:
177                 if amt is None:
178                     # cStringIO doesn't like amt=None
179                     data = self._fp.read()
180                     flush_decoder = True
181                 else:
182                     cache_content = False
183                     data = self._fp.read(amt)
184                     if amt != 0 and not data:  # Platform-specific: Buggy versions of Python.
185                         # Close the connection when no data is returned
186                         #
187                         # This is redundant to what httplib/http.client _should_
188                         # already do.  However, versions of python released before
189                         # December 15, 2012 (http://bugs.python.org/issue16298) do
190                         # not properly close the connection in all cases. There is
191                         # no harm in redundantly calling close.
192                         self._fp.close()
193                         flush_decoder = True
194 
195             except SocketTimeout:
196                 # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
197                 # there is yet no clean way to get at it from this context.
198                 raise ReadTimeoutError(self._pool, None, 'Read timed out.')
199 
200             except BaseSSLError as e:
201                 # FIXME: Is there a better way to differentiate between SSLErrors?
202                 if not 'read operation timed out' in str(e):  # Defensive:
203                     # This shouldn't happen but just in case we're missing an edge
204                     # case, let's avoid swallowing SSL errors.
205                     raise
206 
207                 raise ReadTimeoutError(self._pool, None, 'Read timed out.')
208 
209             except HTTPException as e:
210                 # This includes IncompleteRead.
211                 raise ProtocolError('Connection broken: %r' % e, e)
212 
213             self._fp_bytes_read += len(data)
214 
215             try:
216                 if decode_content and self._decoder:
217                     data = self._decoder.decompress(data)
218             except (IOError, zlib.error) as e:
219                 raise DecodeError(
220                     "Received response with content-encoding: %s, but "
221                     "failed to decode it." % content_encoding, e)
222 
223             if flush_decoder and decode_content and self._decoder:
224                 buf = self._decoder.decompress(binary_type())
225                 data += buf + self._decoder.flush()
226 
227             if cache_content:
228                 self._body = data
229 
230             return data
231 
232         finally:
233             if self._original_response and self._original_response.isclosed():
234                 self.release_conn()
235 
236     def stream(self, amt=2**16, decode_content=None):
237         """
238         A generator wrapper for the read() method. A call will block until
239         ``amt`` bytes have been read from the connection or until the
240         connection is closed.
241 
242         :param amt:
243             How much of the content to read. The generator will return up to
244             much data per iteration, but may return less. This is particularly
245             likely when using compressed data. However, the empty string will
246             never be returned.
247 
248         :param decode_content:
249             If True, will attempt to decode the body based on the
250             'content-encoding' header.
251         """
252         while not is_fp_closed(self._fp):
253             data = self.read(amt=amt, decode_content=decode_content)
254 
255             if data:
256                 yield data
257 
258     @classmethod
259     def from_httplib(ResponseCls, r, **response_kw):
260         """
261         Given an :class:`httplib.HTTPResponse` instance ``r``, return a
262         corresponding :class:`urllib3.response.HTTPResponse` object.
263 
264         Remaining parameters are passed to the HTTPResponse constructor, along
265         with ``original_response=r``.
266         """
267 
268         headers = HTTPHeaderDict()
269         for k, v in r.getheaders():
270             headers.add(k, v)
271 
272         # HTTPResponse objects in Python 3 don't have a .strict attribute
273         strict = getattr(r, 'strict', 0)
274         return ResponseCls(body=r,
275                            headers=headers,
276                            status=r.status,
277                            version=r.version,
278                            reason=r.reason,
279                            strict=strict,
280                            original_response=r,
281                            **response_kw)
282 
283     # Backwards-compatibility methods for httplib.HTTPResponse
284     def getheaders(self):
285         return self.headers
286 
287     def getheader(self, name, default=None):
288         return self.headers.get(name, default)
289 
290     # Overrides from io.IOBase
291     def close(self):
292         if not self.closed:
293             self._fp.close()
294 
295     @property
296     def closed(self):
297         if self._fp is None:
298             return True
299         elif hasattr(self._fp, 'closed'):
300             return self._fp.closed
301         elif hasattr(self._fp, 'isclosed'):  # Python 2
302             return self._fp.isclosed()
303         else:
304             return True
305 
306     def fileno(self):
307         if self._fp is None:
308             raise IOError("HTTPResponse has no file to get a fileno from")
309         elif hasattr(self._fp, "fileno"):
310             return self._fp.fileno()
311         else:
312             raise IOError("The file-like object this HTTPResponse is wrapped "
313                           "around has no file descriptor")
314 
315     def flush(self):
316         if self._fp is not None and hasattr(self._fp, 'flush'):
317             return self._fp.flush()
318 
319     def readable(self):
320         return True
321
```
--- 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/response.py b/urllib3/response.py
--- a/urllib3/response.py
+++ b/urllib3/response.py
@@ -48,7 +48,10 @@
     HTTP Response container.
 
     Backwards-compatible to httplib's HTTPResponse but the response ``body`` is
-    loaded and decoded on-demand when the ``data`` property is accessed.
+    loaded and decoded on-demand when the ``data`` property is accessed.  This
+    class is also compatible with the Python standard library's :mod:`io`
+    module, and can hence be treated as a readable object in the context of that
+    framework.
 
     Extra parameters for behaviour not present in httplib.HTTPResponse:
 
@@ -317,4 +320,14 @@
             return self._fp.flush()
 
     def readable(self):
+        # This method is required for `io` module compatibility.
         return True
+
+    def readinto(self, b):
+        # This method is required for `io` module compatibility.
+        temp = self.read(len(b))
+        if len(temp) == 0:
+            return 0
+        else:
+            b[:len(temp)] = temp
+            return len(temp)

{"golden_diff": "diff --git a/urllib3/response.py b/urllib3/response.py\n--- a/urllib3/response.py\n+++ b/urllib3/response.py\n@@ -48,7 +48,10 @@\n     HTTP Response container.\n \n     Backwards-compatible to httplib's HTTPResponse but the response ``body`` is\n-    loaded and decoded on-demand when the ``data`` property is accessed.\n+    loaded and decoded on-demand when the ``data`` property is accessed.  This\n+    class is also compatible with the Python standard library's :mod:`io`\n+    module, and can hence be treated as a readable object in the context of that\n+    framework.\n \n     Extra parameters for behaviour not present in httplib.HTTPResponse:\n \n@@ -317,4 +320,14 @@\n             return self._fp.flush()\n \n     def readable(self):\n+        # This method is required for `io` module compatibility.\n         return True\n+\n+    def readinto(self, b):\n+        # This method is required for `io` module compatibility.\n+        temp = self.read(len(b))\n+        if len(temp) == 0:\n+            return 0\n+        else:\n+            b[:len(temp)] = temp\n+            return len(temp)\n", "issue": "Add documentation for HTTPResponse `io` support\nReminder for @eteq re #187:\n\n> Would you be up for adding a bit to the documentation/comments which talks about the use cases or benefits of this? That would be greatly appreciated. :)\n\n", "before_files": [{"content": "import zlib\nimport io\nfrom socket import timeout as SocketTimeout\n\nfrom ._collections import HTTPHeaderDict\nfrom .exceptions import ProtocolError, DecodeError, ReadTimeoutError\nfrom .packages.six import string_types as basestring, binary_type\nfrom .connection import HTTPException, BaseSSLError\nfrom .util.response import is_fp_closed\n\n\n\nclass DeflateDecoder(object):\n\n    def __init__(self):\n        self._first_try = True\n        self._data = binary_type()\n        self._obj = zlib.decompressobj()\n\n    def __getattr__(self, name):\n        return getattr(self._obj, name)\n\n    def decompress(self, data):\n        if not self._first_try:\n            return self._obj.decompress(data)\n\n        self._data += data\n        try:\n            return self._obj.decompress(data)\n        except zlib.error:\n            self._first_try = False\n            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)\n            try:\n                return self.decompress(self._data)\n            finally:\n                self._data = None\n\n\ndef _get_decoder(mode):\n    if mode == 'gzip':\n        return zlib.decompressobj(16 + zlib.MAX_WBITS)\n\n    return DeflateDecoder()\n\n\nclass HTTPResponse(io.IOBase):\n    \"\"\"\n    HTTP Response container.\n\n    Backwards-compatible to httplib's HTTPResponse but the response ``body`` is\n    loaded and decoded on-demand when the ``data`` property is accessed.\n\n    Extra parameters for behaviour not present in httplib.HTTPResponse:\n\n    :param preload_content:\n        If True, the response's body will be preloaded during construction.\n\n    :param decode_content:\n        If True, attempts to decode specific content-encoding's based on headers\n        (like 'gzip' and 'deflate') will be skipped and raw data will be used\n        instead.\n\n    :param original_response:\n        When this HTTPResponse wrapper is generated from an httplib.HTTPResponse\n        object, it's convenient to include the original for debug purposes. It's\n        otherwise unused.\n    \"\"\"\n\n    CONTENT_DECODERS = ['gzip', 'deflate']\n    REDIRECT_STATUSES = [301, 302, 303, 307, 308]\n\n    def __init__(self, body='', headers=None, status=0, version=0, reason=None,\n                 strict=0, preload_content=True, decode_content=True,\n                 original_response=None, pool=None, connection=None):\n\n        self.headers = HTTPHeaderDict()\n        if headers:\n            self.headers.update(headers)\n        self.status = status\n        self.version = version\n        self.reason = reason\n        self.strict = strict\n        self.decode_content = decode_content\n\n        self._decoder = None\n        self._body = None\n        self._fp = None\n        self._original_response = original_response\n        self._fp_bytes_read = 0\n\n        if body and isinstance(body, (basestring, binary_type)):\n            self._body = body\n\n        self._pool = pool\n        self._connection = connection\n\n        if hasattr(body, 'read'):\n            self._fp = body\n\n        if preload_content and not self._body:\n            self._body = self.read(decode_content=decode_content)\n\n    def get_redirect_location(self):\n        \"\"\"\n        Should we redirect and where to?\n\n        :returns: Truthy redirect location string if we got a redirect status\n            code and valid location. ``None`` if redirect status and no\n            location. ``False`` if not a redirect status code.\n        \"\"\"\n        if self.status in self.REDIRECT_STATUSES:\n            return self.headers.get('location')\n\n        return False\n\n    def release_conn(self):\n        if not self._pool or not self._connection:\n            return\n\n        self._pool._put_conn(self._connection)\n        self._connection = None\n\n    @property\n    def data(self):\n        # For backwords-compat with earlier urllib3 0.4 and earlier.\n        if self._body:\n            return self._body\n\n        if self._fp:\n            return self.read(cache_content=True)\n\n    def tell(self):\n        \"\"\"\n        Obtain the number of bytes pulled over the wire so far. May differ from\n        the amount of content returned by :meth:``HTTPResponse.read`` if bytes\n        are encoded on the wire (e.g, compressed).\n        \"\"\"\n        return self._fp_bytes_read\n\n    def read(self, amt=None, decode_content=None, cache_content=False):\n        \"\"\"\n        Similar to :meth:`httplib.HTTPResponse.read`, but with two additional\n        parameters: ``decode_content`` and ``cache_content``.\n\n        :param amt:\n            How much of the content to read. If specified, caching is skipped\n            because it doesn't make sense to cache partial content as the full\n            response.\n\n        :param decode_content:\n            If True, will attempt to decode the body based on the\n            'content-encoding' header.\n\n        :param cache_content:\n            If True, will save the returned data such that the same result is\n            returned despite of the state of the underlying file object. This\n            is useful if you want the ``.data`` property to continue working\n            after having ``.read()`` the file object. (Overridden if ``amt`` is\n            set.)\n        \"\"\"\n        # Note: content-encoding value should be case-insensitive, per RFC 7230\n        # Section 3.2\n        content_encoding = self.headers.get('content-encoding', '').lower()\n        if self._decoder is None:\n            if content_encoding in self.CONTENT_DECODERS:\n                self._decoder = _get_decoder(content_encoding)\n        if decode_content is None:\n            decode_content = self.decode_content\n\n        if self._fp is None:\n            return\n\n        flush_decoder = False\n\n        try:\n            try:\n                if amt is None:\n                    # cStringIO doesn't like amt=None\n                    data = self._fp.read()\n                    flush_decoder = True\n                else:\n                    cache_content = False\n                    data = self._fp.read(amt)\n                    if amt != 0 and not data:  # Platform-specific: Buggy versions of Python.\n                        # Close the connection when no data is returned\n                        #\n                        # This is redundant to what httplib/http.client _should_\n                        # already do.  However, versions of python released before\n                        # December 15, 2012 (http://bugs.python.org/issue16298) do\n                        # not properly close the connection in all cases. There is\n                        # no harm in redundantly calling close.\n                        self._fp.close()\n                        flush_decoder = True\n\n            except SocketTimeout:\n                # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but\n                # there is yet no clean way to get at it from this context.\n                raise ReadTimeoutError(self._pool, None, 'Read timed out.')\n\n            except BaseSSLError as e:\n                # FIXME: Is there a better way to differentiate between SSLErrors?\n                if not 'read operation timed out' in str(e):  # Defensive:\n                    # This shouldn't happen but just in case we're missing an edge\n                    # case, let's avoid swallowing SSL errors.\n                    raise\n\n                raise ReadTimeoutError(self._pool, None, 'Read timed out.')\n\n            except HTTPException as e:\n                # This includes IncompleteRead.\n                raise ProtocolError('Connection broken: %r' % e, e)\n\n            self._fp_bytes_read += len(data)\n\n            try:\n                if decode_content and self._decoder:\n                    data = self._decoder.decompress(data)\n            except (IOError, zlib.error) as e:\n                raise DecodeError(\n                    \"Received response with content-encoding: %s, but \"\n                    \"failed to decode it.\" % content_encoding, e)\n\n            if flush_decoder and decode_content and self._decoder:\n                buf = self._decoder.decompress(binary_type())\n                data += buf + self._decoder.flush()\n\n            if cache_content:\n                self._body = data\n\n            return data\n\n        finally:\n            if self._original_response and self._original_response.isclosed():\n                self.release_conn()\n\n    def stream(self, amt=2**16, decode_content=None):\n        \"\"\"\n        A generator wrapper for the read() method. A call will block until\n        ``amt`` bytes have been read from the connection or until the\n        connection is closed.\n\n        :param amt:\n            How much of the content to read. The generator will return up to\n            much data per iteration, but may return less. This is particularly\n            likely when using compressed data. However, the empty string will\n            never be returned.\n\n        :param decode_content:\n            If True, will attempt to decode the body based on the\n            'content-encoding' header.\n        \"\"\"\n        while not is_fp_closed(self._fp):\n            data = self.read(amt=amt, decode_content=decode_content)\n\n            if data:\n                yield data\n\n    @classmethod\n    def from_httplib(ResponseCls, r, **response_kw):\n        \"\"\"\n        Given an :class:`httplib.HTTPResponse` instance ``r``, return a\n        corresponding :class:`urllib3.response.HTTPResponse` object.\n\n        Remaining parameters are passed to the HTTPResponse constructor, along\n        with ``original_response=r``.\n        \"\"\"\n\n        headers = HTTPHeaderDict()\n        for k, v in r.getheaders():\n            headers.add(k, v)\n\n        # HTTPResponse objects in Python 3 don't have a .strict attribute\n        strict = getattr(r, 'strict', 0)\n        return ResponseCls(body=r,\n                           headers=headers,\n                           status=r.status,\n                           version=r.version,\n                           reason=r.reason,\n                           strict=strict,\n                           original_response=r,\n                           **response_kw)\n\n    # Backwards-compatibility methods for httplib.HTTPResponse\n    def getheaders(self):\n        return self.headers\n\n    def getheader(self, name, default=None):\n        return self.headers.get(name, default)\n\n    # Overrides from io.IOBase\n    def close(self):\n        if not self.closed:\n            self._fp.close()\n\n    @property\n    def closed(self):\n        if self._fp is None:\n            return True\n        elif hasattr(self._fp, 'closed'):\n            return self._fp.closed\n        elif hasattr(self._fp, 'isclosed'):  # Python 2\n            return self._fp.isclosed()\n        else:\n            return True\n\n    def fileno(self):\n        if self._fp is None:\n            raise IOError(\"HTTPResponse has no file to get a fileno from\")\n        elif hasattr(self._fp, \"fileno\"):\n            return self._fp.fileno()\n        else:\n            raise IOError(\"The file-like object this HTTPResponse is wrapped \"\n                          \"around has no file descriptor\")\n\n    def flush(self):\n        if self._fp is not None and hasattr(self._fp, 'flush'):\n            return self._fp.flush()\n\n    def readable(self):\n        return True\n", "path": "urllib3/response.py"}], "after_files": [{"content": "import zlib\nimport io\nfrom socket import timeout as SocketTimeout\n\nfrom ._collections import HTTPHeaderDict\nfrom .exceptions import ProtocolError, DecodeError, ReadTimeoutError\nfrom .packages.six import string_types as basestring, binary_type\nfrom .connection import HTTPException, BaseSSLError\nfrom .util.response import is_fp_closed\n\n\n\nclass DeflateDecoder(object):\n\n    def __init__(self):\n        self._first_try = True\n        self._data = binary_type()\n        self._obj = zlib.decompressobj()\n\n    def __getattr__(self, name):\n        return getattr(self._obj, name)\n\n    def decompress(self, data):\n        if not self._first_try:\n            return self._obj.decompress(data)\n\n        self._data += data\n        try:\n            return self._obj.decompress(data)\n        except zlib.error:\n            self._first_try = False\n            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)\n            try:\n                return self.decompress(self._data)\n            finally:\n                self._data = None\n\n\ndef _get_decoder(mode):\n    if mode == 'gzip':\n        return zlib.decompressobj(16 + zlib.MAX_WBITS)\n\n    return DeflateDecoder()\n\n\nclass HTTPResponse(io.IOBase):\n    \"\"\"\n    HTTP Response container.\n\n    Backwards-compatible to httplib's HTTPResponse but the response ``body`` is\n    loaded and decoded on-demand when the ``data`` property is accessed.  This\n    class is also compatible with the Python standard library's :mod:`io`\n    module, and can hence be treated as a readable object in the context of that\n    framework.\n\n    Extra parameters for behaviour not present in httplib.HTTPResponse:\n\n    :param preload_content:\n        If True, the response's body will be preloaded during construction.\n\n    :param decode_content:\n        If True, attempts to decode specific content-encoding's based on headers\n        (like 'gzip' and 'deflate') will be skipped and raw data will be used\n        instead.\n\n    :param original_response:\n        When this HTTPResponse wrapper is generated from an httplib.HTTPResponse\n        object, it's convenient to include the original for debug purposes. It's\n        otherwise unused.\n    \"\"\"\n\n    CONTENT_DECODERS = ['gzip', 'deflate']\n    REDIRECT_STATUSES = [301, 302, 303, 307, 308]\n\n    def __init__(self, body='', headers=None, status=0, version=0, reason=None,\n                 strict=0, preload_content=True, decode_content=True,\n                 original_response=None, pool=None, connection=None):\n\n        self.headers = HTTPHeaderDict()\n        if headers:\n            self.headers.update(headers)\n        self.status = status\n        self.version = version\n        self.reason = reason\n        self.strict = strict\n        self.decode_content = decode_content\n\n        self._decoder = None\n        self._body = None\n        self._fp = None\n        self._original_response = original_response\n        self._fp_bytes_read = 0\n\n        if body and isinstance(body, (basestring, binary_type)):\n            self._body = body\n\n        self._pool = pool\n        self._connection = connection\n\n        if hasattr(body, 'read'):\n            self._fp = body\n\n        if preload_content and not self._body:\n            self._body = self.read(decode_content=decode_content)\n\n    def get_redirect_location(self):\n        \"\"\"\n        Should we redirect and where to?\n\n        :returns: Truthy redirect location string if we got a redirect status\n            code and valid location. ``None`` if redirect status and no\n            location. ``False`` if not a redirect status code.\n        \"\"\"\n        if self.status in self.REDIRECT_STATUSES:\n            return self.headers.get('location')\n\n        return False\n\n    def release_conn(self):\n        if not self._pool or not self._connection:\n            return\n\n        self._pool._put_conn(self._connection)\n        self._connection = None\n\n    @property\n    def data(self):\n        # For backwords-compat with earlier urllib3 0.4 and earlier.\n        if self._body:\n            return self._body\n\n        if self._fp:\n            return self.read(cache_content=True)\n\n    def tell(self):\n        \"\"\"\n        Obtain the number of bytes pulled over the wire so far. May differ from\n        the amount of content returned by :meth:``HTTPResponse.read`` if bytes\n        are encoded on the wire (e.g, compressed).\n        \"\"\"\n        return self._fp_bytes_read\n\n    def read(self, amt=None, decode_content=None, cache_content=False):\n        \"\"\"\n        Similar to :meth:`httplib.HTTPResponse.read`, but with two additional\n        parameters: ``decode_content`` and ``cache_content``.\n\n        :param amt:\n            How much of the content to read. If specified, caching is skipped\n            because it doesn't make sense to cache partial content as the full\n            response.\n\n        :param decode_content:\n            If True, will attempt to decode the body based on the\n            'content-encoding' header.\n\n        :param cache_content:\n            If True, will save the returned data such that the same result is\n            returned despite of the state of the underlying file object. This\n            is useful if you want the ``.data`` property to continue working\n            after having ``.read()`` the file object. (Overridden if ``amt`` is\n            set.)\n        \"\"\"\n        # Note: content-encoding value should be case-insensitive, per RFC 7230\n        # Section 3.2\n        content_encoding = self.headers.get('content-encoding', '').lower()\n        if self._decoder is None:\n            if content_encoding in self.CONTENT_DECODERS:\n                self._decoder = _get_decoder(content_encoding)\n        if decode_content is None:\n            decode_content = self.decode_content\n\n        if self._fp is None:\n            return\n\n        flush_decoder = False\n\n        try:\n            try:\n                if amt is None:\n                    # cStringIO doesn't like amt=None\n                    data = self._fp.read()\n                    flush_decoder = True\n                else:\n                    cache_content = False\n                    data = self._fp.read(amt)\n                    if amt != 0 and not data:  # Platform-specific: Buggy versions of Python.\n                        # Close the connection when no data is returned\n                        #\n                        # This is redundant to what httplib/http.client _should_\n                        # already do.  However, versions of python released before\n                        # December 15, 2012 (http://bugs.python.org/issue16298) do\n                        # not properly close the connection in all cases. There is\n                        # no harm in redundantly calling close.\n                        self._fp.close()\n                        flush_decoder = True\n\n            except SocketTimeout:\n                # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but\n                # there is yet no clean way to get at it from this context.\n                raise ReadTimeoutError(self._pool, None, 'Read timed out.')\n\n            except BaseSSLError as e:\n                # FIXME: Is there a better way to differentiate between SSLErrors?\n                if not 'read operation timed out' in str(e):  # Defensive:\n                    # This shouldn't happen but just in case we're missing an edge\n                    # case, let's avoid swallowing SSL errors.\n                    raise\n\n                raise ReadTimeoutError(self._pool, None, 'Read timed out.')\n\n            except HTTPException as e:\n                # This includes IncompleteRead.\n                raise ProtocolError('Connection broken: %r' % e, e)\n\n            self._fp_bytes_read += len(data)\n\n            try:\n                if decode_content and self._decoder:\n                    data = self._decoder.decompress(data)\n            except (IOError, zlib.error) as e:\n                raise DecodeError(\n                    \"Received response with content-encoding: %s, but \"\n                    \"failed to decode it.\" % content_encoding, e)\n\n            if flush_decoder and decode_content and self._decoder:\n                buf = self._decoder.decompress(binary_type())\n                data += buf + self._decoder.flush()\n\n            if cache_content:\n                self._body = data\n\n            return data\n\n        finally:\n            if self._original_response and self._original_response.isclosed():\n                self.release_conn()\n\n    def stream(self, amt=2**16, decode_content=None):\n        \"\"\"\n        A generator wrapper for the read() method. A call will block until\n        ``amt`` bytes have been read from the connection or until the\n        connection is closed.\n\n        :param amt:\n            How much of the content to read. The generator will return up to\n            much data per iteration, but may return less. This is particularly\n            likely when using compressed data. However, the empty string will\n            never be returned.\n\n        :param decode_content:\n            If True, will attempt to decode the body based on the\n            'content-encoding' header.\n        \"\"\"\n        while not is_fp_closed(self._fp):\n            data = self.read(amt=amt, decode_content=decode_content)\n\n            if data:\n                yield data\n\n    @classmethod\n    def from_httplib(ResponseCls, r, **response_kw):\n        \"\"\"\n        Given an :class:`httplib.HTTPResponse` instance ``r``, return a\n        corresponding :class:`urllib3.response.HTTPResponse` object.\n\n        Remaining parameters are passed to the HTTPResponse constructor, along\n        with ``original_response=r``.\n        \"\"\"\n\n        headers = HTTPHeaderDict()\n        for k, v in r.getheaders():\n            headers.add(k, v)\n\n        # HTTPResponse objects in Python 3 don't have a .strict attribute\n        strict = getattr(r, 'strict', 0)\n        return ResponseCls(body=r,\n                           headers=headers,\n                           status=r.status,\n                           version=r.version,\n                           reason=r.reason,\n                           strict=strict,\n                           original_response=r,\n                           **response_kw)\n\n    # Backwards-compatibility methods for httplib.HTTPResponse\n    def getheaders(self):\n        return self.headers\n\n    def getheader(self, name, default=None):\n        return self.headers.get(name, default)\n\n    # Overrides from io.IOBase\n    def close(self):\n        if not self.closed:\n            self._fp.close()\n\n    @property\n    def closed(self):\n        if self._fp is None:\n            return True\n        elif hasattr(self._fp, 'closed'):\n            return self._fp.closed\n        elif hasattr(self._fp, 'isclosed'):  # Python 2\n            return self._fp.isclosed()\n        else:\n            return True\n\n    def fileno(self):\n        if self._fp is None:\n            raise IOError(\"HTTPResponse has no file to get a fileno from\")\n        elif hasattr(self._fp, \"fileno\"):\n            return self._fp.fileno()\n        else:\n            raise IOError(\"The file-like object this HTTPResponse is wrapped \"\n                          \"around has no file descriptor\")\n\n    def flush(self):\n        if self._fp is not None and hasattr(self._fp, 'flush'):\n            return self._fp.flush()\n\n    def readable(self):\n        # This method is required for `io` module compatibility.\n        return True\n\n    def readinto(self, b):\n        # This method is required for `io` module compatibility.\n        temp = self.read(len(b))\n        if len(temp) == 0:\n            return 0\n        else:\n            b[:len(temp)] = temp\n            return len(temp)\n", "path": "urllib3/response.py"}]}