|
6 | 6 | Contains the HTTP/2.0 equivalent of the HTTPResponse object defined in
|
7 | 7 | httplib/http.client.
|
8 | 8 | """
|
| 9 | +import zlib |
| 10 | + |
| 11 | + |
9 | 12 | class HTTP20Response(object):
|
10 | 13 | """
|
11 | 14 | An ``HTTP20Response`` wraps the HTTP/2.0 response from the server. It
|
@@ -36,22 +39,40 @@ def __init__(self, headers, stream):
|
36 | 39 | # may need to buffer some for incomplete reads.
|
37 | 40 | self._data_buffer = b''
|
38 | 41 |
|
39 |
| - def read(self, amt=None): |
| 42 | + # This object is used for decompressing gzipped request bodies. Right |
| 43 | + # now we only support gzip because that's all the RFC mandates of us. |
| 44 | + # Later we'll add support for more encodings. |
| 45 | + # This 16 + MAX_WBITS nonsense is to force gzip. See this |
| 46 | + # Stack Overflow answer for more: |
| 47 | + # http://stackoverflow.com/a/2695466/1401686 |
| 48 | + self._decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS) |
| 49 | + |
| 50 | + def read(self, amt=None, decode_content=True): |
40 | 51 | """
|
41 | 52 | Reads the response body, or up to the next ``amt`` bytes.
|
42 | 53 | """
|
43 | 54 | if amt is not None and amt <= len(self._data_buffer):
|
44 | 55 | data = self._data_buffer[:amt]
|
45 | 56 | self._data_buffer = self._data_buffer[amt:]
|
46 |
| - return data |
| 57 | + flush_buffer = False |
47 | 58 | elif amt is not None:
|
48 | 59 | read_amt = amt - len(self._data_buffer)
|
49 | 60 | self._data_buffer += self._stream._read(read_amt)
|
50 | 61 | data = self._data_buffer[:amt]
|
51 | 62 | self._data_buffer = self._data_buffer[amt:]
|
52 |
| - return data |
| 63 | + flush_buffer = len(data) < amt |
53 | 64 | else:
|
54 |
| - return b''.join([self._data_buffer, self._stream._read()]) |
| 65 | + data = b''.join([self._data_buffer, self._stream._read()]) |
| 66 | + flush_buffer = True |
| 67 | + |
| 68 | + # We may need to decode the body. |
| 69 | + if (decode_content and self.getheader('content-encoding', False)): |
| 70 | + data = self._decompressobj.decompress(data) |
| 71 | + |
| 72 | + if flush_buffer: |
| 73 | + data += self._decompressobj.flush() |
| 74 | + |
| 75 | + return data |
55 | 76 |
|
56 | 77 | def getheader(self, name, default=None):
|
57 | 78 | """
|
|
0 commit comments