'Similar to :meth:`httplib.HTTPResponse.read`, but with two additional
parameters: ``decode_content`` and ``cache_content``.
:param amt:
How much of the content to read. If specified, caching is skipped
because it doesn\'t make sense to cache partial content as the full
response.
:param decode_content:
If True, will attempt to decode the body based on the
\'content-encoding\' header.
:param cache_content:
If True, will save the returned data such that the same result is
returned despite of the state of the underlying file object. This
is useful if you want the ``.data`` property to continue working
after having ``.read()`` the file object. (Overridden if ``amt`` is
set.)'

def read(self, amt=None, decode_content=None, cache_content=False):

    self._init_decoder()
    if (decode_content is None):
        decode_content = self.decode_content
    if (self._fp is None):
        return
    flush_decoder = False
    try:
        try:
            if (amt is None):
                data = self._fp.read()
                flush_decoder = True
            else:
                cache_content = False
                data = self._fp.read(amt)
                if ((amt != 0) and (not data)):
                    self._fp.close()
                    flush_decoder = True
        except SocketTimeout:
            raise ReadTimeoutError(self._pool, None, 'Read    timed    out.')
        except BaseSSLError as e:
            if ('read    operation    timed    out' not in str(e)):
                raise
            raise ReadTimeoutError(self._pool, None, 'Read    timed    out.')
        except HTTPException as e:
            raise ProtocolError(('Connection    broken:    %r' % e), e)
        self._fp_bytes_read += len(data)
        data = self._decode(data, decode_content, flush_decoder)
        if cache_content:
            self._body = data
        return data
    finally:
        if (self._original_response and self._original_response.isclosed()):
            self.release_conn()
