| Index: third_party/requests/packages/urllib3/response.py
|
| diff --git a/third_party/requests/packages/urllib3/response.py b/third_party/requests/packages/urllib3/response.py
|
| index 2fa407887de5c4f7eaba3f80f1de5ce6916fa562..4efff5a13b6b0056be176ce591b09bbd94ede12f 100644
|
| --- a/third_party/requests/packages/urllib3/response.py
|
| +++ b/third_party/requests/packages/urllib3/response.py
|
| @@ -1,5 +1,5 @@
|
| # urllib3/response.py
|
| -# Copyright 2008-2012 Andrey Petrov and contributors (see CONTRIBUTORS.txt)
|
| +# Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt)
|
| #
|
| # This module is part of urllib3 and is released under
|
| # the MIT License: http://www.opensource.org/licenses/mit-license.php
|
| @@ -7,9 +7,11 @@
|
|
|
| import logging
|
| import zlib
|
| +import io
|
|
|
| from .exceptions import DecodeError
|
| from .packages.six import string_types as basestring, binary_type
|
| +from .util import is_fp_closed
|
|
|
|
|
| log = logging.getLogger(__name__)
|
| @@ -48,7 +50,7 @@ def _get_decoder(mode):
|
| return DeflateDecoder()
|
|
|
|
|
| -class HTTPResponse(object):
|
| +class HTTPResponse(io.IOBase):
|
| """
|
| HTTP Response container.
|
|
|
| @@ -72,6 +74,7 @@ class HTTPResponse(object):
|
| """
|
|
|
| CONTENT_DECODERS = ['gzip', 'deflate']
|
| + REDIRECT_STATUSES = [301, 302, 303, 307, 308]
|
|
|
| def __init__(self, body='', headers=None, status=0, version=0, reason=None,
|
| strict=0, preload_content=True, decode_content=True,
|
| @@ -105,7 +108,7 @@ class HTTPResponse(object):
|
| code and valid location. ``None`` if redirect status and no
|
| location. ``False`` if not a redirect status code.
|
| """
|
| - if self.status in [301, 302, 303, 307]:
|
| + if self.status in self.REDIRECT_STATUSES:
|
| return self.headers.get('location')
|
|
|
| return False
|
| @@ -183,11 +186,13 @@ class HTTPResponse(object):
|
| try:
|
| if decode_content and self._decoder:
|
| data = self._decoder.decompress(data)
|
| - except (IOError, zlib.error):
|
| - raise DecodeError("Received response with content-encoding: %s, but "
|
| - "failed to decode it." % content_encoding)
|
| + except (IOError, zlib.error) as e:
|
| + raise DecodeError(
|
| + "Received response with content-encoding: %s, but "
|
| + "failed to decode it." % content_encoding,
|
| + e)
|
|
|
| - if flush_decoder and self._decoder:
|
| + if flush_decoder and decode_content and self._decoder:
|
| buf = self._decoder.decompress(binary_type())
|
| data += buf + self._decoder.flush()
|
|
|
| @@ -200,6 +205,29 @@ class HTTPResponse(object):
|
| if self._original_response and self._original_response.isclosed():
|
| self.release_conn()
|
|
|
| + def stream(self, amt=2**16, decode_content=None):
|
| + """
|
| + A generator wrapper for the read() method. A call will block until
|
| + ``amt`` bytes have been read from the connection or until the
|
| + connection is closed.
|
| +
|
| + :param amt:
|
| + How much of the content to read. The generator will return up to
|
| + much data per iteration, but may return less. This is particularly
|
| + likely when using compressed data. However, the empty string will
|
| + never be returned.
|
| +
|
| + :param decode_content:
|
| + If True, will attempt to decode the body based on the
|
| + 'content-encoding' header.
|
| + """
|
| + while not is_fp_closed(self._fp):
|
| + data = self.read(amt=amt, decode_content=decode_content)
|
| +
|
| + if data:
|
| + yield data
|
| +
|
| +
|
| @classmethod
|
| def from_httplib(ResponseCls, r, **response_kw):
|
| """
|
| @@ -239,3 +267,35 @@ class HTTPResponse(object):
|
|
|
| def getheader(self, name, default=None):
|
| return self.headers.get(name, default)
|
| +
|
| + # Overrides from io.IOBase
|
| + def close(self):
|
| + if not self.closed:
|
| + self._fp.close()
|
| +
|
| + @property
|
| + def closed(self):
|
| + if self._fp is None:
|
| + return True
|
| + elif hasattr(self._fp, 'closed'):
|
| + return self._fp.closed
|
| + elif hasattr(self._fp, 'isclosed'): # Python 2
|
| + return self._fp.isclosed()
|
| + else:
|
| + return True
|
| +
|
| + def fileno(self):
|
| + if self._fp is None:
|
| + raise IOError("HTTPResponse has no file to get a fileno from")
|
| + elif hasattr(self._fp, "fileno"):
|
| + return self._fp.fileno()
|
| + else:
|
| + raise IOError("The file-like object this HTTPResponse is wrapped "
|
| + "around has no file descriptor")
|
| +
|
| + def flush(self):
|
| + if self._fp is not None and hasattr(self._fp, 'flush'):
|
| + return self._fp.flush()
|
| +
|
| + def readable(self):
|
| + return True
|
|
|