'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
    data = None
    with self._error_catcher():
        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
    if data:
        self._fp_bytes_read += len(data)
        data = self._decode(data, decode_content, flush_decoder)
        if cache_content:
            self._body = data
    return data
