| 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
 | 
| 
 |