Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/urllib3/response.py: 20%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

744 statements  

1from __future__ import annotations 

2 

3import collections 

4import io 

5import json as _json 

6import logging 

7import socket 

8import sys 

9import typing 

10import warnings 

11import zlib 

12from contextlib import contextmanager 

13from http.client import HTTPMessage as _HttplibHTTPMessage 

14from http.client import HTTPResponse as _HttplibHTTPResponse 

15from socket import timeout as SocketTimeout 

16 

17if typing.TYPE_CHECKING: 

18 from ._base_connection import BaseHTTPConnection 

19 

20try: 

21 try: 

22 import brotlicffi as brotli # type: ignore[import-not-found] 

23 except ImportError: 

24 import brotli # type: ignore[import-not-found] 

25except ImportError: 

26 brotli = None 

27 

28from . import util 

29from ._base_connection import _TYPE_BODY 

30from ._collections import HTTPHeaderDict 

31from .connection import BaseSSLError, HTTPConnection, HTTPException 

32from .exceptions import ( 

33 BodyNotHttplibCompatible, 

34 DecodeError, 

35 DependencyWarning, 

36 HTTPError, 

37 IncompleteRead, 

38 InvalidChunkLength, 

39 InvalidHeader, 

40 ProtocolError, 

41 ReadTimeoutError, 

42 ResponseNotChunked, 

43 SSLError, 

44) 

45from .util.response import is_fp_closed, is_response_to_head 

46from .util.retry import Retry 

47 

48if typing.TYPE_CHECKING: 

49 from .connectionpool import HTTPConnectionPool 

50 

51log = logging.getLogger(__name__) 

52 

53# Read in 64 KiB chunks 

54_READ_CHUNK_SIZE = 2**16 

55 

56 

57class ContentDecoder: 

58 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

59 raise NotImplementedError() 

60 

61 @property 

62 def has_unconsumed_tail(self) -> bool: 

63 raise NotImplementedError() 

64 

65 def flush(self) -> bytes: 

66 raise NotImplementedError() 

67 

68 

69class DeflateDecoder(ContentDecoder): 

70 def __init__(self) -> None: 

71 self._first_try = True 

72 self._first_try_data = b"" 

73 self._unfed_data = b"" 

74 self._obj = zlib.decompressobj() 

75 

76 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

77 data = self._unfed_data + data 

78 self._unfed_data = b"" 

79 if not data and not self._obj.unconsumed_tail: 

80 return data 

81 original_max_length = max_length 

82 if original_max_length < 0: 

83 max_length = 0 

84 elif original_max_length == 0: 

85 # We should not pass 0 to the zlib decompressor because 0 is 

86 # the default value that will make zlib decompress without a 

87 # length limit. 

88 # Data should be stored for subsequent calls. 

89 self._unfed_data = data 

90 return b"" 

91 

92 # Subsequent calls always reuse `self._obj`. zlib requires 

93 # passing the unconsumed tail if decompression is to continue. 

94 if not self._first_try: 

95 return self._obj.decompress( 

96 self._obj.unconsumed_tail + data, max_length=max_length 

97 ) 

98 

99 # First call tries with RFC 1950 ZLIB format. 

100 self._first_try_data += data 

101 try: 

102 decompressed = self._obj.decompress(data, max_length=max_length) 

103 if decompressed: 

104 self._first_try = False 

105 self._first_try_data = b"" 

106 return decompressed 

107 # On failure, it falls back to RFC 1951 DEFLATE format. 

108 except zlib.error: 

109 self._first_try = False 

110 self._obj = zlib.decompressobj(-zlib.MAX_WBITS) 

111 try: 

112 return self.decompress( 

113 self._first_try_data, max_length=original_max_length 

114 ) 

115 finally: 

116 self._first_try_data = b"" 

117 

118 @property 

119 def has_unconsumed_tail(self) -> bool: 

120 return bool(self._unfed_data) or ( 

121 bool(self._obj.unconsumed_tail) and not self._first_try 

122 ) 

123 

124 def flush(self) -> bytes: 

125 return self._obj.flush() 

126 

127 

128class GzipDecoderState: 

129 FIRST_MEMBER = 0 

130 OTHER_MEMBERS = 1 

131 SWALLOW_DATA = 2 

132 

133 

134class GzipDecoder(ContentDecoder): 

135 def __init__(self) -> None: 

136 self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) 

137 self._state = GzipDecoderState.FIRST_MEMBER 

138 self._unconsumed_tail = b"" 

139 

140 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

141 ret = bytearray() 

142 if self._state == GzipDecoderState.SWALLOW_DATA: 

143 return bytes(ret) 

144 

145 if max_length == 0: 

146 # We should not pass 0 to the zlib decompressor because 0 is 

147 # the default value that will make zlib decompress without a 

148 # length limit. 

149 # Data should be stored for subsequent calls. 

150 self._unconsumed_tail += data 

151 return b"" 

152 

153 # zlib requires passing the unconsumed tail to the subsequent 

154 # call if decompression is to continue. 

155 data = self._unconsumed_tail + data 

156 if not data and self._obj.eof: 

157 return bytes(ret) 

158 

159 while True: 

160 try: 

161 ret += self._obj.decompress( 

162 data, max_length=max(max_length - len(ret), 0) 

163 ) 

164 except zlib.error: 

165 previous_state = self._state 

166 # Ignore data after the first error 

167 self._state = GzipDecoderState.SWALLOW_DATA 

168 self._unconsumed_tail = b"" 

169 if previous_state == GzipDecoderState.OTHER_MEMBERS: 

170 # Allow trailing garbage acceptable in other gzip clients 

171 return bytes(ret) 

172 raise 

173 

174 self._unconsumed_tail = data = ( 

175 self._obj.unconsumed_tail or self._obj.unused_data 

176 ) 

177 if max_length > 0 and len(ret) >= max_length: 

178 break 

179 

180 if not data: 

181 return bytes(ret) 

182 # When the end of a gzip member is reached, a new decompressor 

183 # must be created for unused (possibly future) data. 

184 if self._obj.eof: 

185 self._state = GzipDecoderState.OTHER_MEMBERS 

186 self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) 

187 

188 return bytes(ret) 

189 

190 @property 

191 def has_unconsumed_tail(self) -> bool: 

192 return bool(self._unconsumed_tail) 

193 

194 def flush(self) -> bytes: 

195 return self._obj.flush() 

196 

197 

198if brotli is not None: 

199 

200 class BrotliDecoder(ContentDecoder): 

201 # Supports both 'brotlipy' and 'Brotli' packages 

202 # since they share an import name. The top branches 

203 # are for 'brotlipy' and bottom branches for 'Brotli' 

204 def __init__(self) -> None: 

205 self._obj = brotli.Decompressor() 

206 if hasattr(self._obj, "decompress"): 

207 setattr(self, "_decompress", self._obj.decompress) 

208 else: 

209 setattr(self, "_decompress", self._obj.process) 

210 

211 # Requires Brotli >= 1.2.0 for `output_buffer_limit`. 

212 def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: 

213 raise NotImplementedError() 

214 

215 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

216 try: 

217 if max_length > 0: 

218 return self._decompress(data, output_buffer_limit=max_length) 

219 else: 

220 return self._decompress(data) 

221 except TypeError: 

222 # Fallback for Brotli/brotlicffi/brotlipy versions without 

223 # the `output_buffer_limit` parameter. 

224 warnings.warn( 

225 "Brotli >= 1.2.0 is required to prevent decompression bombs.", 

226 DependencyWarning, 

227 ) 

228 return self._decompress(data) 

229 

230 @property 

231 def has_unconsumed_tail(self) -> bool: 

232 try: 

233 return not self._obj.can_accept_more_data() 

234 except AttributeError: 

235 return False 

236 

237 def flush(self) -> bytes: 

238 if hasattr(self._obj, "flush"): 

239 return self._obj.flush() # type: ignore[no-any-return] 

240 return b"" 

241 

242 

243try: 

244 if sys.version_info >= (3, 14): 

245 from compression import zstd 

246 else: 

247 from backports import zstd 

248except ImportError: 

249 HAS_ZSTD = False 

250else: 

251 HAS_ZSTD = True 

252 

253 class ZstdDecoder(ContentDecoder): 

254 def __init__(self) -> None: 

255 self._obj = zstd.ZstdDecompressor() 

256 

257 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

258 if not data and not self.has_unconsumed_tail: 

259 return b"" 

260 if self._obj.eof: 

261 data = self._obj.unused_data + data 

262 self._obj = zstd.ZstdDecompressor() 

263 part = self._obj.decompress(data, max_length=max_length) 

264 length = len(part) 

265 data_parts = [part] 

266 # Every loop iteration is supposed to read data from a separate frame. 

267 # The loop breaks when: 

268 # - enough data is read; 

269 # - no more unused data is available; 

270 # - end of the last read frame has not been reached (i.e., 

271 # more data has to be fed). 

272 while ( 

273 self._obj.eof 

274 and self._obj.unused_data 

275 and (max_length < 0 or length < max_length) 

276 ): 

277 unused_data = self._obj.unused_data 

278 if not self._obj.needs_input: 

279 self._obj = zstd.ZstdDecompressor() 

280 part = self._obj.decompress( 

281 unused_data, 

282 max_length=(max_length - length) if max_length > 0 else -1, 

283 ) 

284 if part_length := len(part): 

285 data_parts.append(part) 

286 length += part_length 

287 elif self._obj.needs_input: 

288 break 

289 return b"".join(data_parts) 

290 

291 @property 

292 def has_unconsumed_tail(self) -> bool: 

293 return not (self._obj.needs_input or self._obj.eof) or bool( 

294 self._obj.unused_data 

295 ) 

296 

297 def flush(self) -> bytes: 

298 if not self._obj.eof: 

299 raise DecodeError("Zstandard data is incomplete") 

300 return b"" 

301 

302 

303class MultiDecoder(ContentDecoder): 

304 """ 

305 From RFC7231: 

306 If one or more encodings have been applied to a representation, the 

307 sender that applied the encodings MUST generate a Content-Encoding 

308 header field that lists the content codings in the order in which 

309 they were applied. 

310 """ 

311 

312 # Maximum allowed number of chained HTTP encodings in the 

313 # Content-Encoding header. 

314 max_decode_links = 5 

315 

316 def __init__(self, modes: str) -> None: 

317 encodings = [m.strip() for m in modes.split(",")] 

318 if len(encodings) > self.max_decode_links: 

319 raise DecodeError( 

320 "Too many content encodings in the chain: " 

321 f"{len(encodings)} > {self.max_decode_links}" 

322 ) 

323 self._decoders = [_get_decoder(e) for e in encodings] 

324 

325 def flush(self) -> bytes: 

326 return self._decoders[0].flush() 

327 

328 def decompress(self, data: bytes, max_length: int = -1) -> bytes: 

329 if max_length <= 0: 

330 for d in reversed(self._decoders): 

331 data = d.decompress(data) 

332 return data 

333 

334 ret = bytearray() 

335 # Every while loop iteration goes through all decoders once. 

336 # It exits when enough data is read or no more data can be read. 

337 # It is possible that the while loop iteration does not produce 

338 # any data because we retrieve up to `max_length` from every 

339 # decoder, and the amount of bytes may be insufficient for the 

340 # next decoder to produce enough/any output. 

341 while True: 

342 any_data = False 

343 for d in reversed(self._decoders): 

344 data = d.decompress(data, max_length=max_length - len(ret)) 

345 if data: 

346 any_data = True 

347 # We should not break when no data is returned because 

348 # next decoders may produce data even with empty input. 

349 ret += data 

350 if not any_data or len(ret) >= max_length: 

351 return bytes(ret) 

352 data = b"" 

353 

354 @property 

355 def has_unconsumed_tail(self) -> bool: 

356 return any(d.has_unconsumed_tail for d in self._decoders) 

357 

358 

359def _get_decoder(mode: str) -> ContentDecoder: 

360 if "," in mode: 

361 return MultiDecoder(mode) 

362 

363 # According to RFC 9110 section 8.4.1.3, recipients should 

364 # consider x-gzip equivalent to gzip 

365 if mode in ("gzip", "x-gzip"): 

366 return GzipDecoder() 

367 

368 if brotli is not None and mode == "br": 

369 return BrotliDecoder() 

370 

371 if HAS_ZSTD and mode == "zstd": 

372 return ZstdDecoder() 

373 

374 return DeflateDecoder() 

375 

376 

377class BytesQueueBuffer: 

378 """Memory-efficient bytes buffer 

379 

380 To return decoded data in read() and still follow the BufferedIOBase API, we need a 

381 buffer to always return the correct amount of bytes. 

382 

383 This buffer should be filled using calls to put() 

384 

385 Our maximum memory usage is determined by the sum of the size of: 

386 

387 * self.buffer, which contains the full data 

388 * the largest chunk that we will copy in get() 

389 """ 

390 

391 def __init__(self) -> None: 

392 self.buffer: typing.Deque[bytes | memoryview[bytes]] = collections.deque() 

393 self._size: int = 0 

394 

395 def __len__(self) -> int: 

396 return self._size 

397 

398 def put(self, data: bytes) -> None: 

399 self.buffer.append(data) 

400 self._size += len(data) 

401 

402 def get(self, n: int) -> bytes: 

403 if n == 0: 

404 return b"" 

405 elif not self.buffer: 

406 raise RuntimeError("buffer is empty") 

407 elif n < 0: 

408 raise ValueError("n should be > 0") 

409 

410 if len(self.buffer[0]) == n and isinstance(self.buffer[0], bytes): 

411 self._size -= n 

412 return self.buffer.popleft() 

413 

414 fetched = 0 

415 ret = io.BytesIO() 

416 while fetched < n: 

417 remaining = n - fetched 

418 chunk = self.buffer.popleft() 

419 chunk_length = len(chunk) 

420 if remaining < chunk_length: 

421 chunk = memoryview(chunk) 

422 left_chunk, right_chunk = chunk[:remaining], chunk[remaining:] 

423 ret.write(left_chunk) 

424 self.buffer.appendleft(right_chunk) 

425 self._size -= remaining 

426 break 

427 else: 

428 ret.write(chunk) 

429 self._size -= chunk_length 

430 fetched += chunk_length 

431 

432 if not self.buffer: 

433 break 

434 

435 return ret.getvalue() 

436 

437 def get_all(self) -> bytes: 

438 buffer = self.buffer 

439 if not buffer: 

440 assert self._size == 0 

441 return b"" 

442 if len(buffer) == 1: 

443 result = buffer.pop() 

444 if isinstance(result, memoryview): 

445 result = result.tobytes() 

446 else: 

447 ret = io.BytesIO() 

448 ret.writelines(buffer.popleft() for _ in range(len(buffer))) 

449 result = ret.getvalue() 

450 self._size = 0 

451 return result 

452 

453 

454class BaseHTTPResponse(io.IOBase): 

455 CONTENT_DECODERS = ["gzip", "x-gzip", "deflate"] 

456 if brotli is not None: 

457 CONTENT_DECODERS += ["br"] 

458 if HAS_ZSTD: 

459 CONTENT_DECODERS += ["zstd"] 

460 REDIRECT_STATUSES = [301, 302, 303, 307, 308] 

461 

462 DECODER_ERROR_CLASSES: tuple[type[Exception], ...] = (IOError, zlib.error) 

463 if brotli is not None: 

464 DECODER_ERROR_CLASSES += (brotli.error,) 

465 

466 if HAS_ZSTD: 

467 DECODER_ERROR_CLASSES += (zstd.ZstdError,) 

468 

469 def __init__( 

470 self, 

471 *, 

472 headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None, 

473 status: int, 

474 version: int, 

475 version_string: str, 

476 reason: str | None, 

477 decode_content: bool, 

478 request_url: str | None, 

479 retries: Retry | None = None, 

480 ) -> None: 

481 if isinstance(headers, HTTPHeaderDict): 

482 self.headers = headers 

483 else: 

484 self.headers = HTTPHeaderDict(headers) # type: ignore[arg-type] 

485 self.status = status 

486 self.version = version 

487 self.version_string = version_string 

488 self.reason = reason 

489 self.decode_content = decode_content 

490 self._has_decoded_content = False 

491 self._request_url: str | None = request_url 

492 self.retries = retries 

493 

494 self.chunked = False 

495 tr_enc = self.headers.get("transfer-encoding", "").lower() 

496 # Don't incur the penalty of creating a list and then discarding it 

497 encodings = (enc.strip() for enc in tr_enc.split(",")) 

498 if "chunked" in encodings: 

499 self.chunked = True 

500 

501 self._decoder: ContentDecoder | None = None 

502 # Distinguish an uninitialized decoder from a response needing no decoder. 

503 self._decoder_initialized = False 

504 self.length_remaining: int | None 

505 

506 def get_redirect_location(self) -> str | None | typing.Literal[False]: 

507 """ 

508 Should we redirect and where to? 

509 

510 :returns: Truthy redirect location string if we got a redirect status 

511 code and valid location. ``None`` if redirect status and no 

512 location. ``False`` if not a redirect status code. 

513 """ 

514 if self.status in self.REDIRECT_STATUSES: 

515 return self.headers.get("location") 

516 return False 

517 

518 @property 

519 def data(self) -> bytes: 

520 raise NotImplementedError() 

521 

522 def json(self) -> typing.Any: 

523 """ 

524 Deserializes the body of the HTTP response as a Python object. 

525 

526 The body of the HTTP response must be encoded using UTF-8, as per 

527 `RFC 8529 Section 8.1 <https://www.rfc-editor.org/rfc/rfc8259#section-8.1>`_. 

528 

529 To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to 

530 your custom decoder instead. 

531 

532 If the body of the HTTP response is not decodable to UTF-8, a 

533 `UnicodeDecodeError` will be raised. If the body of the HTTP response is not a 

534 valid JSON document, a `json.JSONDecodeError` will be raised. 

535 

536 Read more :ref:`here <json_content>`. 

537 

538 :returns: The body of the HTTP response as a Python object. 

539 """ 

540 data = self.data.decode("utf-8") 

541 return _json.loads(data) 

542 

543 @property 

544 def url(self) -> str | None: 

545 raise NotImplementedError() 

546 

547 @url.setter 

548 def url(self, url: str | None) -> None: 

549 raise NotImplementedError() 

550 

551 @property 

552 def connection(self) -> BaseHTTPConnection | None: 

553 raise NotImplementedError() 

554 

555 @property 

556 def retries(self) -> Retry | None: 

557 return self._retries 

558 

559 @retries.setter 

560 def retries(self, retries: Retry | None) -> None: 

561 # Override the request_url if retries has a redirect location. 

562 if retries is not None and retries.history: 

563 self.url = retries.history[-1].redirect_location 

564 self._retries = retries 

565 

566 def stream( 

567 self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None 

568 ) -> typing.Iterator[bytes]: 

569 raise NotImplementedError() 

570 

571 def read( 

572 self, 

573 amt: int | None = None, 

574 decode_content: bool | None = None, 

575 cache_content: bool = False, 

576 ) -> bytes: 

577 raise NotImplementedError() 

578 

579 def read1( 

580 self, 

581 amt: int | None = None, 

582 decode_content: bool | None = None, 

583 ) -> bytes: 

584 raise NotImplementedError() 

585 

586 def read_chunked( 

587 self, 

588 amt: int | None = None, 

589 decode_content: bool | None = None, 

590 ) -> typing.Iterator[bytes]: 

591 raise NotImplementedError() 

592 

593 def release_conn(self) -> None: 

594 raise NotImplementedError() 

595 

596 def drain_conn(self) -> None: 

597 raise NotImplementedError() 

598 

599 def shutdown(self) -> None: 

600 raise NotImplementedError() 

601 

602 def close(self) -> None: 

603 raise NotImplementedError() 

604 

605 def _init_decoder(self) -> None: 

606 """ 

607 Set-up the _decoder attribute if necessary. 

608 """ 

609 if self._decoder_initialized: 

610 return 

611 

612 if self._decoder is None: 

613 # Note: content-encoding value should be case-insensitive, per RFC 7230 

614 # Section 3.2 

615 content_encoding = self.headers.get("content-encoding", "").lower() 

616 if content_encoding in self.CONTENT_DECODERS: 

617 self._decoder = _get_decoder(content_encoding) 

618 elif "," in content_encoding: 

619 encodings = [ 

620 e.strip() 

621 for e in content_encoding.split(",") 

622 if e.strip() in self.CONTENT_DECODERS 

623 ] 

624 if encodings: 

625 self._decoder = _get_decoder(content_encoding) 

626 

627 self._decoder_initialized = True 

628 

629 def _decode( 

630 self, 

631 data: bytes, 

632 decode_content: bool | None, 

633 flush_decoder: bool, 

634 max_length: int | None = None, 

635 ) -> bytes: 

636 """ 

637 Decode the data passed in and potentially flush the decoder. 

638 """ 

639 if not decode_content: 

640 if self._has_decoded_content: 

641 raise RuntimeError( 

642 "Calling read(decode_content=False) is not supported after " 

643 "read(decode_content=True) was called." 

644 ) 

645 return data 

646 

647 if max_length is None or flush_decoder: 

648 max_length = -1 

649 

650 try: 

651 if self._decoder: 

652 data = self._decoder.decompress(data, max_length=max_length) 

653 self._has_decoded_content = True 

654 except self.DECODER_ERROR_CLASSES as e: 

655 content_encoding = self.headers.get("content-encoding", "").lower() 

656 raise DecodeError( 

657 "Received response with content-encoding: %s, but " 

658 "failed to decode it." % content_encoding, 

659 e, 

660 ) from e 

661 if flush_decoder: 

662 data += self._flush_decoder() 

663 

664 return data 

665 

666 def _flush_decoder(self) -> bytes: 

667 """ 

668 Flushes the decoder. Should only be called if the decoder is actually 

669 being used. 

670 """ 

671 if self._decoder: 

672 return self._decoder.decompress(b"") + self._decoder.flush() 

673 return b"" 

674 

675 # Compatibility methods for `io` module 

676 def readinto(self, b: bytearray | memoryview[int]) -> int: 

677 temp = self.read(len(b)) 

678 if len(temp) == 0: 

679 return 0 

680 else: 

681 b[: len(temp)] = temp 

682 return len(temp) 

683 

684 # Methods used by dependent libraries 

685 def getheaders(self) -> HTTPHeaderDict: 

686 return self.headers 

687 

688 def getheader(self, name: str, default: str | None = None) -> str | None: 

689 return self.headers.get(name, default) 

690 

691 # Compatibility method for http.cookiejar 

692 def info(self) -> HTTPHeaderDict: 

693 return self.headers 

694 

695 def geturl(self) -> str | None: 

696 return self.url 

697 

698 

699class HTTPResponse(BaseHTTPResponse): 

700 """ 

701 HTTP Response container. 

702 

703 Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is 

704 loaded and decoded on-demand when the ``data`` property is accessed. This 

705 class is also compatible with the Python standard library's :mod:`io` 

706 module, and can hence be treated as a readable object in the context of that 

707 framework. 

708 

709 Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`: 

710 

711 :param preload_content: 

712 If True, the response's body will be preloaded during construction. 

713 

714 :param decode_content: 

715 If True, will attempt to decode the body based on the 

716 'content-encoding' header. 

717 

718 :param original_response: 

719 When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse` 

720 object, it's convenient to include the original for debug purposes. It's 

721 otherwise unused. 

722 

723 :param retries: 

724 The retries contains the last :class:`~urllib3.util.retry.Retry` that 

725 was used during the request. 

726 

727 :param enforce_content_length: 

728 Enforce content length checking. Body returned by server must match 

729 value of Content-Length header, if present. Otherwise, raise error. 

730 """ 

731 

732 def __init__( 

733 self, 

734 body: _TYPE_BODY = "", 

735 headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None, 

736 status: int = 0, 

737 version: int = 0, 

738 version_string: str = "HTTP/?", 

739 reason: str | None = None, 

740 preload_content: bool = True, 

741 decode_content: bool = True, 

742 original_response: _HttplibHTTPResponse | None = None, 

743 pool: HTTPConnectionPool | None = None, 

744 connection: HTTPConnection | None = None, 

745 msg: _HttplibHTTPMessage | None = None, 

746 retries: Retry | None = None, 

747 enforce_content_length: bool = True, 

748 request_method: str | None = None, 

749 request_url: str | None = None, 

750 auto_close: bool = True, 

751 sock_shutdown: typing.Callable[[int], None] | None = None, 

752 ) -> None: 

753 super().__init__( 

754 headers=headers, 

755 status=status, 

756 version=version, 

757 version_string=version_string, 

758 reason=reason, 

759 decode_content=decode_content, 

760 request_url=request_url, 

761 retries=retries, 

762 ) 

763 

764 self.enforce_content_length = enforce_content_length 

765 self.auto_close = auto_close 

766 

767 self._body = None 

768 self._uncached_read_occurred = False 

769 self._fp: _HttplibHTTPResponse | None = None 

770 self._original_response = original_response 

771 self._fp_bytes_read = 0 

772 self.msg = msg 

773 

774 if body and isinstance(body, (str, bytes)): 

775 self._body = body 

776 

777 self._pool = pool 

778 self._connection = connection 

779 

780 if hasattr(body, "read"): 

781 self._fp = body # type: ignore[assignment] 

782 self._sock_shutdown = sock_shutdown 

783 

784 # Are we using the chunked-style of transfer encoding? 

785 self.chunk_left: int | None = None 

786 

787 # Determine length of response 

788 self.length_remaining = self._init_length(request_method) 

789 

790 # Used to return the correct amount of bytes for partial read()s 

791 self._decoded_buffer = BytesQueueBuffer() 

792 

793 # If requested, preload the body. 

794 if preload_content and not self._body: 

795 self._body = self.read(decode_content=decode_content) 

796 

797 def release_conn(self) -> None: 

798 if not self._pool or not self._connection: 

799 return None 

800 

801 self._pool._put_conn(self._connection) 

802 self._connection = None 

803 

804 def drain_conn(self) -> None: 

805 """ 

806 Read and discard any remaining HTTP response data in the response connection. 

807 

808 Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. 

809 """ 

810 try: 

811 while self._raw_read(_READ_CHUNK_SIZE): 

812 pass 

813 except (HTTPError, OSError, BaseSSLError, HTTPException): 

814 pass 

815 if self._has_decoded_content: 

816 # `_raw_read` skips decompression, so we should clean up the 

817 # decoder to avoid keeping unnecessary data in memory. 

818 self._decoded_buffer = BytesQueueBuffer() 

819 self._decoder = None 

820 

821 @property 

822 def data(self) -> bytes: 

823 # For backwards-compat with earlier urllib3 0.4 and earlier. 

824 if self._body: 

825 return self._body # type: ignore[return-value] 

826 

827 if self._fp: 

828 return self.read(cache_content=True) 

829 

830 return None # type: ignore[return-value] 

831 

832 @property 

833 def connection(self) -> HTTPConnection | None: 

834 return self._connection 

835 

836 def isclosed(self) -> bool: 

837 return is_fp_closed(self._fp) 

838 

839 def tell(self) -> int: 

840 """ 

841 Obtain the number of bytes pulled over the wire so far. May differ from 

842 the amount of content returned by :meth:`HTTPResponse.read` 

843 if bytes are encoded on the wire (e.g, compressed). 

844 """ 

845 return self._fp_bytes_read 

846 

847 def _init_length(self, request_method: str | None) -> int | None: 

848 """ 

849 Set initial length value for Response content if available. 

850 """ 

851 length: int | None 

852 content_length: str | None = self.headers.get("content-length") 

853 

854 if content_length is not None: 

855 if self.chunked: 

856 # This Response will fail with an IncompleteRead if it can't be 

857 # received as chunked. This method falls back to attempt reading 

858 # the response before raising an exception. 

859 log.warning( 

860 "Received response with both Content-Length and " 

861 "Transfer-Encoding set. This is expressly forbidden " 

862 "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " 

863 "attempting to process response as Transfer-Encoding: " 

864 "chunked." 

865 ) 

866 return None 

867 

868 try: 

869 # RFC 7230 section 3.3.2 specifies multiple content lengths can 

870 # be sent in a single Content-Length header 

871 # (e.g. Content-Length: 42, 42). This line ensures the values 

872 # are all valid ints and that as long as the `set` length is 1, 

873 # all values are the same. Otherwise, the header is invalid. 

874 lengths = {int(val) for val in content_length.split(",")} 

875 if len(lengths) > 1: 

876 raise InvalidHeader( 

877 "Content-Length contained multiple " 

878 "unmatching values (%s)" % content_length 

879 ) 

880 length = lengths.pop() 

881 except ValueError: 

882 length = None 

883 else: 

884 if length < 0: 

885 length = None 

886 

887 else: # if content_length is None 

888 length = None 

889 

890 # Convert status to int for comparison 

891 # In some cases, httplib returns a status of "_UNKNOWN" 

892 try: 

893 status = int(self.status) 

894 except ValueError: 

895 status = 0 

896 

897 # Check for responses that shouldn't include a body 

898 if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD": 

899 length = 0 

900 

901 return length 

902 

903 @contextmanager 

904 def _error_catcher(self) -> typing.Generator[None]: 

905 """ 

906 Catch low-level python exceptions, instead re-raising urllib3 

907 variants, so that low-level exceptions are not leaked in the 

908 high-level api. 

909 

910 On exit, release the connection back to the pool. 

911 """ 

912 clean_exit = False 

913 

914 try: 

915 try: 

916 yield 

917 

918 except SocketTimeout as e: 

919 # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but 

920 # there is yet no clean way to get at it from this context. 

921 raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] 

922 

923 except BaseSSLError as e: 

924 # SSL errors related to framing/MAC get wrapped and reraised here 

925 raise SSLError(e) from e 

926 

927 except IncompleteRead as e: 

928 if ( 

929 e.expected is not None 

930 and e.partial is not None 

931 and e.expected == -e.partial 

932 ): 

933 arg = "Response may not contain content." 

934 else: 

935 arg = f"Connection broken: {e!r}" 

936 raise ProtocolError(arg, e) from e 

937 

938 except (HTTPException, OSError) as e: 

939 raise ProtocolError(f"Connection broken: {e!r}", e) from e 

940 

941 # If no exception is thrown, we should avoid cleaning up 

942 # unnecessarily. 

943 clean_exit = True 

944 finally: 

945 # If we didn't terminate cleanly, we need to throw away our 

946 # connection. 

947 if not clean_exit: 

948 # The response may not be closed but we're not going to use it 

949 # anymore so close it now to ensure that the connection is 

950 # released back to the pool. 

951 if self._original_response: 

952 self._original_response.close() 

953 

954 # Closing the response may not actually be sufficient to close 

955 # everything, so if we have a hold of the connection close that 

956 # too. 

957 if self._connection: 

958 self._connection.close() 

959 

960 # If we hold the original response but it's closed now, we should 

961 # return the connection back to the pool. 

962 if self._original_response and self._original_response.isclosed(): 

963 self.release_conn() 

964 

965 def _fp_read( 

966 self, 

967 amt: int | None = None, 

968 *, 

969 read1: bool = False, 

970 ) -> bytes: 

971 """ 

972 Read a response with the thought that reading the number of bytes 

973 larger than can fit in a 32-bit int at a time via SSL in some 

974 known cases leads to an overflow error that has to be prevented 

975 if `amt` or `self.length_remaining` indicate that a problem may 

976 happen. 

977 

978 This happens to urllib3 injected with pyOpenSSL-backed SSL-support. 

979 """ 

980 assert self._fp 

981 c_int_max = 2**31 - 1 

982 if ( 

983 (amt and amt > c_int_max) 

984 or ( 

985 amt is None 

986 and self.length_remaining 

987 and self.length_remaining > c_int_max 

988 ) 

989 ) and util.IS_PYOPENSSL: 

990 if read1: 

991 return self._fp.read1(c_int_max) 

992 buffer = io.BytesIO() 

993 # Besides `max_chunk_amt` being a maximum chunk size, it 

994 # affects memory overhead of reading a response by this 

995 # method in CPython. 

996 # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum 

997 # chunk size that does not lead to an overflow error, but 

998 # 256 MiB is a compromise. 

999 max_chunk_amt = 2**28 

1000 while amt is None or amt != 0: 

1001 if amt is not None: 

1002 chunk_amt = min(amt, max_chunk_amt) 

1003 amt -= chunk_amt 

1004 else: 

1005 chunk_amt = max_chunk_amt 

1006 data = self._fp.read(chunk_amt) 

1007 if not data: 

1008 break 

1009 buffer.write(data) 

1010 del data # to reduce peak memory usage by `max_chunk_amt`. 

1011 return buffer.getvalue() 

1012 elif read1: 

1013 return self._fp.read1(amt) if amt is not None else self._fp.read1() 

1014 else: 

1015 # StringIO doesn't like amt=None 

1016 return self._fp.read(amt) if amt is not None else self._fp.read() 

1017 

1018 def _raw_read( 

1019 self, 

1020 amt: int | None = None, 

1021 *, 

1022 read1: bool = False, 

1023 ) -> bytes: 

1024 """ 

1025 Reads `amt` of bytes from the socket. 

1026 """ 

1027 if self._fp is None: 

1028 return None # type: ignore[return-value] 

1029 

1030 fp_closed = getattr(self._fp, "closed", False) 

1031 

1032 with self._error_catcher(): 

1033 data = self._fp_read(amt, read1=read1) if not fp_closed else b"" 

1034 if amt is not None and amt != 0 and not data: 

1035 # Platform-specific: Buggy versions of Python. 

1036 # Close the connection when no data is returned 

1037 # 

1038 # This is redundant to what httplib/http.client _should_ 

1039 # already do. However, versions of python released before 

1040 # December 15, 2012 (http://bugs.python.org/issue16298) do 

1041 # not properly close the connection in all cases. There is 

1042 # no harm in redundantly calling close. 

1043 self._fp.close() 

1044 if ( 

1045 self.enforce_content_length 

1046 and self.length_remaining is not None 

1047 and self.length_remaining != 0 

1048 ): 

1049 # This is an edge case that httplib failed to cover due 

1050 # to concerns of backward compatibility. We're 

1051 # addressing it here to make sure IncompleteRead is 

1052 # raised during streaming, so all calls with incorrect 

1053 # Content-Length are caught. 

1054 raise IncompleteRead(self._fp_bytes_read, self.length_remaining) 

1055 elif read1 and ( 

1056 (amt != 0 and not data) or self.length_remaining == len(data) 

1057 ): 

1058 # All data has been read, but `self._fp.read1` in 

1059 # CPython 3.12 and older doesn't always close 

1060 # `http.client.HTTPResponse`, so we close it here. 

1061 # See https://github.com/python/cpython/issues/113199 

1062 self._fp.close() 

1063 

1064 if data: 

1065 self._fp_bytes_read += len(data) 

1066 if self.length_remaining is not None: 

1067 self.length_remaining -= len(data) 

1068 return data 

1069 

1070 def read( 

1071 self, 

1072 amt: int | None = None, 

1073 decode_content: bool | None = None, 

1074 cache_content: bool = False, 

1075 ) -> bytes: 

1076 """ 

1077 Similar to :meth:`http.client.HTTPResponse.read`, but with two additional 

1078 parameters: ``decode_content`` and ``cache_content``. 

1079 

1080 :param amt: 

1081 How much of the content to read. If specified, caching is skipped 

1082 because it doesn't make sense to cache partial content as the full 

1083 response. 

1084 

1085 :param decode_content: 

1086 If True, will attempt to decode the body based on the 

1087 'content-encoding' header. 

1088 

1089 :param cache_content: 

1090 If True, will save the returned data such that the same result is 

1091 returned despite of the state of the underlying file object. This 

1092 is useful if you want the ``.data`` property to continue working 

1093 after having ``.read()`` the file object. (Overridden if ``amt`` is 

1094 set.) 

1095 """ 

1096 self._init_decoder() 

1097 if decode_content is None: 

1098 decode_content = self.decode_content 

1099 

1100 if amt and amt < 0: 

1101 # Negative numbers and `None` should be treated the same. 

1102 amt = None 

1103 elif amt is not None: 

1104 cache_content = False 

1105 

1106 if ( 

1107 self._decoder 

1108 and self._decoder.has_unconsumed_tail 

1109 and len(self._decoded_buffer) < amt 

1110 ): 

1111 decoded_data = self._decode( 

1112 b"", 

1113 decode_content, 

1114 flush_decoder=False, 

1115 max_length=amt - len(self._decoded_buffer), 

1116 ) 

1117 self._decoded_buffer.put(decoded_data) 

1118 if len(self._decoded_buffer) >= amt: 

1119 return self._decoded_buffer.get(amt) 

1120 

1121 data = self._raw_read(amt) 

1122 if not cache_content: 

1123 self._uncached_read_occurred = True 

1124 

1125 flush_decoder = amt is None or (amt != 0 and not data) 

1126 

1127 if ( 

1128 not data 

1129 and len(self._decoded_buffer) == 0 

1130 and not (self._decoder and self._decoder.has_unconsumed_tail) 

1131 ): 

1132 return data 

1133 

1134 if amt is None: 

1135 data = self._decode(data, decode_content, flush_decoder) 

1136 # It's possible that there is buffered decoded data after a 

1137 # partial read. 

1138 if decode_content and len(self._decoded_buffer) > 0: 

1139 self._decoded_buffer.put(data) 

1140 data = self._decoded_buffer.get_all() 

1141 

1142 if cache_content and not self._uncached_read_occurred: 

1143 self._body = data 

1144 else: 

1145 # do not waste memory on buffer when not decoding 

1146 if not decode_content: 

1147 if self._has_decoded_content: 

1148 raise RuntimeError( 

1149 "Calling read(decode_content=False) is not supported after " 

1150 "read(decode_content=True) was called." 

1151 ) 

1152 return data 

1153 

1154 decoded_data = self._decode( 

1155 data, 

1156 decode_content, 

1157 flush_decoder, 

1158 max_length=amt - len(self._decoded_buffer), 

1159 ) 

1160 self._decoded_buffer.put(decoded_data) 

1161 

1162 while len(self._decoded_buffer) < amt and data: 

1163 # TODO make sure to initially read enough data to get past the headers 

1164 # For example, the GZ file header takes 10 bytes, we don't want to read 

1165 # it one byte at a time 

1166 data = self._raw_read(amt) 

1167 decoded_data = self._decode( 

1168 data, 

1169 decode_content, 

1170 flush_decoder, 

1171 max_length=amt - len(self._decoded_buffer), 

1172 ) 

1173 self._decoded_buffer.put(decoded_data) 

1174 data = self._decoded_buffer.get(amt) 

1175 

1176 return data 

1177 

1178 def read1( 

1179 self, 

1180 amt: int | None = None, 

1181 decode_content: bool | None = None, 

1182 ) -> bytes: 

1183 """ 

1184 Similar to ``http.client.HTTPResponse.read1`` and documented 

1185 in :meth:`io.BufferedReader.read1`, but with an additional parameter: 

1186 ``decode_content``. 

1187 

1188 :param amt: 

1189 How much of the content to read. 

1190 

1191 :param decode_content: 

1192 If True, will attempt to decode the body based on the 

1193 'content-encoding' header. 

1194 """ 

1195 if decode_content is None: 

1196 decode_content = self.decode_content 

1197 if amt and amt < 0: 

1198 # Negative numbers and `None` should be treated the same. 

1199 amt = None 

1200 # try and respond without going to the network 

1201 if self._has_decoded_content: 

1202 if not decode_content: 

1203 raise RuntimeError( 

1204 "Calling read1(decode_content=False) is not supported after " 

1205 "read1(decode_content=True) was called." 

1206 ) 

1207 if ( 

1208 self._decoder 

1209 and self._decoder.has_unconsumed_tail 

1210 and (amt is None or len(self._decoded_buffer) < amt) 

1211 ): 

1212 decoded_data = self._decode( 

1213 b"", 

1214 decode_content, 

1215 flush_decoder=False, 

1216 max_length=( 

1217 amt - len(self._decoded_buffer) if amt is not None else None 

1218 ), 

1219 ) 

1220 self._decoded_buffer.put(decoded_data) 

1221 if len(self._decoded_buffer) > 0: 

1222 if amt is None: 

1223 return self._decoded_buffer.get_all() 

1224 return self._decoded_buffer.get(amt) 

1225 if amt == 0: 

1226 return b"" 

1227 

1228 # FIXME, this method's type doesn't say returning None is possible 

1229 data = self._raw_read(amt, read1=True) 

1230 self._uncached_read_occurred = True 

1231 if not decode_content or data is None: 

1232 return data 

1233 

1234 self._init_decoder() 

1235 while True: 

1236 flush_decoder = not data 

1237 decoded_data = self._decode( 

1238 data, decode_content, flush_decoder, max_length=amt 

1239 ) 

1240 self._decoded_buffer.put(decoded_data) 

1241 if decoded_data or flush_decoder: 

1242 break 

1243 data = self._raw_read(8192, read1=True) 

1244 

1245 if amt is None: 

1246 return self._decoded_buffer.get_all() 

1247 return self._decoded_buffer.get(amt) 

1248 

1249 def stream( 

1250 self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None 

1251 ) -> typing.Generator[bytes]: 

1252 """ 

1253 A generator wrapper for the read() method. A call will block until 

1254 ``amt`` bytes have been read from the connection or until the 

1255 connection is closed. 

1256 

1257 :param amt: 

1258 How much of the content to read. The generator will return up to 

1259 much data per iteration, but may return less. This is particularly 

1260 likely when using compressed data. However, the empty string will 

1261 never be returned. 

1262 

1263 :param decode_content: 

1264 If True, will attempt to decode the body based on the 

1265 'content-encoding' header. 

1266 """ 

1267 if amt == 0: 

1268 return 

1269 

1270 if self.chunked and self.supports_chunked_reads(): 

1271 yield from self.read_chunked(amt, decode_content=decode_content) 

1272 else: 

1273 while ( 

1274 not is_fp_closed(self._fp) 

1275 or len(self._decoded_buffer) > 0 

1276 or (self._decoder and self._decoder.has_unconsumed_tail) 

1277 ): 

1278 data = self.read(amt=amt, decode_content=decode_content) 

1279 

1280 if data: 

1281 yield data 

1282 

1283 # Overrides from io.IOBase 

1284 def readable(self) -> bool: 

1285 return True 

1286 

1287 def shutdown(self) -> None: 

1288 if not self._sock_shutdown: 

1289 raise ValueError("Cannot shutdown socket as self._sock_shutdown is not set") 

1290 if self._connection is None: 

1291 raise RuntimeError( 

1292 "Cannot shutdown as connection has already been released to the pool" 

1293 ) 

1294 self._sock_shutdown(socket.SHUT_RD) 

1295 

1296 def close(self) -> None: 

1297 self._sock_shutdown = None 

1298 

1299 if not self.closed and self._fp: 

1300 self._fp.close() 

1301 

1302 if self._connection: 

1303 self._connection.close() 

1304 

1305 if not self.auto_close: 

1306 io.IOBase.close(self) 

1307 

1308 @property 

1309 def closed(self) -> bool: 

1310 if not self.auto_close: 

1311 return io.IOBase.closed.__get__(self) # type: ignore[no-any-return] 

1312 elif self._fp is None: 

1313 return True 

1314 elif hasattr(self._fp, "isclosed"): 

1315 return self._fp.isclosed() 

1316 elif hasattr(self._fp, "closed"): 

1317 return self._fp.closed 

1318 else: 

1319 return True 

1320 

1321 def fileno(self) -> int: 

1322 if self._fp is None: 

1323 raise OSError("HTTPResponse has no file to get a fileno from") 

1324 elif hasattr(self._fp, "fileno"): 

1325 return self._fp.fileno() 

1326 else: 

1327 raise OSError( 

1328 "The file-like object this HTTPResponse is wrapped " 

1329 "around has no file descriptor" 

1330 ) 

1331 

1332 def flush(self) -> None: 

1333 if ( 

1334 self._fp is not None 

1335 and hasattr(self._fp, "flush") 

1336 and not getattr(self._fp, "closed", False) 

1337 ): 

1338 return self._fp.flush() 

1339 

1340 def supports_chunked_reads(self) -> bool: 

1341 """ 

1342 Checks if the underlying file-like object looks like a 

1343 :class:`http.client.HTTPResponse` object. We do this by testing for 

1344 the fp attribute. If it is present we assume it returns raw chunks as 

1345 processed by read_chunked(). 

1346 """ 

1347 return hasattr(self._fp, "fp") 

1348 

1349 def _update_chunk_length(self) -> None: 

1350 # First, we'll figure out length of a chunk and then 

1351 # we'll try to read it from socket. 

1352 if self.chunk_left is not None: 

1353 return None 

1354 line = self._fp.fp.readline() # type: ignore[union-attr] 

1355 line = line.split(b";", 1)[0] 

1356 try: 

1357 self.chunk_left = int(line, 16) 

1358 except ValueError: 

1359 self.close() 

1360 if line: 

1361 # Invalid chunked protocol response, abort. 

1362 raise InvalidChunkLength(self, line) from None 

1363 else: 

1364 # Truncated at start of next chunk 

1365 raise ProtocolError("Response ended prematurely") from None 

1366 

1367 def _handle_chunk(self, amt: int | None) -> bytes: 

1368 returned_chunk = None 

1369 if amt is None: 

1370 chunk = self._fp._safe_read(self.chunk_left) # type: ignore[union-attr] 

1371 returned_chunk = chunk 

1372 self._fp._safe_read(2) # type: ignore[union-attr] # Toss the CRLF at the end of the chunk. 

1373 self.chunk_left = None 

1374 elif self.chunk_left is not None and amt < self.chunk_left: 

1375 value = self._fp._safe_read(amt) # type: ignore[union-attr] 

1376 self.chunk_left = self.chunk_left - amt 

1377 returned_chunk = value 

1378 elif amt == self.chunk_left: 

1379 value = self._fp._safe_read(amt) # type: ignore[union-attr] 

1380 self._fp._safe_read(2) # type: ignore[union-attr] # Toss the CRLF at the end of the chunk. 

1381 self.chunk_left = None 

1382 returned_chunk = value 

1383 else: # amt > self.chunk_left 

1384 returned_chunk = self._fp._safe_read(self.chunk_left) # type: ignore[union-attr] 

1385 self._fp._safe_read(2) # type: ignore[union-attr] # Toss the CRLF at the end of the chunk. 

1386 self.chunk_left = None 

1387 return returned_chunk # type: ignore[no-any-return] 

1388 

1389 def read_chunked( 

1390 self, amt: int | None = None, decode_content: bool | None = None 

1391 ) -> typing.Generator[bytes]: 

1392 """ 

1393 Similar to :meth:`HTTPResponse.read`, but with an additional 

1394 parameter: ``decode_content``. 

1395 

1396 :param amt: 

1397 How much of the content to read. If specified, caching is skipped 

1398 because it doesn't make sense to cache partial content as the full 

1399 response. 

1400 

1401 :param decode_content: 

1402 If True, will attempt to decode the body based on the 

1403 'content-encoding' header. 

1404 """ 

1405 self._init_decoder() 

1406 # FIXME: Rewrite this method and make it a class with a better structured logic. 

1407 if not self.chunked: 

1408 raise ResponseNotChunked( 

1409 "Response is not chunked. " 

1410 "Header 'transfer-encoding: chunked' is missing." 

1411 ) 

1412 if not self.supports_chunked_reads(): 

1413 raise BodyNotHttplibCompatible( 

1414 "Body should be http.client.HTTPResponse like. " 

1415 "It should have have an fp attribute which returns raw chunks." 

1416 ) 

1417 

1418 with self._error_catcher(): 

1419 # Don't bother reading the body of a HEAD request. 

1420 if self._original_response and is_response_to_head(self._original_response): 

1421 self._original_response.close() 

1422 return None 

1423 

1424 # If a response is already read and closed 

1425 # then return immediately. 

1426 if self._fp.fp is None: # type: ignore[union-attr] 

1427 return None 

1428 

1429 if amt == 0: 

1430 return 

1431 elif amt and amt < 0: 

1432 # Negative numbers and `None` should be treated the same, 

1433 # but httplib handles only `None` correctly. 

1434 amt = None 

1435 

1436 while True: 

1437 # First, check if any data is left in the decoder's buffer. 

1438 if self._decoder and self._decoder.has_unconsumed_tail: 

1439 chunk = b"" 

1440 else: 

1441 self._update_chunk_length() 

1442 self._uncached_read_occurred = True 

1443 if self.chunk_left == 0: 

1444 break 

1445 chunk = self._handle_chunk(amt) 

1446 decoded = self._decode( 

1447 chunk, 

1448 decode_content=decode_content, 

1449 flush_decoder=False, 

1450 max_length=amt, 

1451 ) 

1452 if decoded: 

1453 yield decoded 

1454 

1455 if decode_content: 

1456 # On CPython and PyPy, we should never need to flush the 

1457 # decoder. However, on Jython we *might* need to, so 

1458 # lets defensively do it anyway. 

1459 decoded = self._flush_decoder() 

1460 if decoded: # Platform-specific: Jython. 

1461 yield decoded 

1462 

1463 # Chunk content ends with \r\n: discard it. 

1464 while self._fp is not None: 

1465 line = self._fp.fp.readline() 

1466 if not line: 

1467 # Some sites may not end with '\r\n'. 

1468 break 

1469 if line == b"\r\n": 

1470 break 

1471 

1472 # We read everything; close the "file". 

1473 if self._original_response: 

1474 self._original_response.close() 

1475 

1476 @property 

1477 def url(self) -> str | None: 

1478 """ 

1479 Returns the URL that was the source of this response. 

1480 If the request that generated this response redirected, this method 

1481 will return the final redirect location. 

1482 """ 

1483 return self._request_url 

1484 

1485 @url.setter 

1486 def url(self, url: str | None) -> None: 

1487 self._request_url = url 

1488 

1489 def __iter__(self) -> typing.Iterator[bytes]: 

1490 buffer: list[bytes] = [] 

1491 for chunk in self.stream(decode_content=True): 

1492 if b"\n" in chunk: 

1493 chunks = chunk.split(b"\n") 

1494 yield b"".join(buffer) + chunks[0] + b"\n" 

1495 for x in chunks[1:-1]: 

1496 yield x + b"\n" 

1497 if chunks[-1]: 

1498 buffer = [chunks[-1]] 

1499 else: 

1500 buffer = [] 

1501 else: 

1502 buffer.append(chunk) 

1503 if buffer: 

1504 yield b"".join(buffer)