MCPcopy
hub / github.com/urllib3/urllib3 / decompress

Method decompress

src/urllib3/response.py:137–185  ·  view source on GitHub ↗
(self, data: bytes, max_length: int = -1)

Source from the content-addressed store, hash-verified

135 self._unconsumed_tail = b""
136
137 def decompress(self, data: bytes, max_length: int = -1) -> bytes:
138 ret = bytearray()
139 if self._state == GzipDecoderState.SWALLOW_DATA:
140 return bytes(ret)
141
142 if max_length == 0:
143 # We should not pass 0 to the zlib decompressor because 0 is
144 # the default value that will make zlib decompress without a
145 # length limit.
146 # Data should be stored for subsequent calls.
147 self._unconsumed_tail += data
148 return b""
149
150 # zlib requires passing the unconsumed tail to the subsequent
151 # call if decompression is to continue.
152 data = self._unconsumed_tail + data
153 if not data and self._obj.eof:
154 return bytes(ret)
155
156 while True:
157 try:
158 ret += self._obj.decompress(
159 data, max_length=max(max_length - len(ret), 0)
160 )
161 except zlib.error:
162 previous_state = self._state
163 # Ignore data after the first error
164 self._state = GzipDecoderState.SWALLOW_DATA
165 self._unconsumed_tail = b""
166 if previous_state == GzipDecoderState.OTHER_MEMBERS:
167 # Allow trailing garbage acceptable in other gzip clients
168 return bytes(ret)
169 raise
170
171 self._unconsumed_tail = data = (
172 self._obj.unconsumed_tail or self._obj.unused_data
173 )
174 if max_length > 0 and len(ret) >= max_length:
175 break
176
177 if not data:
178 return bytes(ret)
179 # When the end of a gzip member is reached, a new decompressor
180 # must be created for unused (possibly future) data.
181 if self._obj.eof:
182 self._state = GzipDecoderState.OTHER_MEMBERS
183 self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
184
185 return bytes(ret)
186
187 @property
188 def has_unconsumed_tail(self) -> bool:

Calls

no outgoing calls