]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/pip/_vendor/urllib3/response.py
1 from __future__
import absolute_import
8 from contextlib
import contextmanager
9 from socket
import error
as SocketError
10 from socket
import timeout
as SocketTimeout
15 from ._collections
import HTTPHeaderDict
16 from .connection
import BaseSSLError
, HTTPException
17 from .exceptions
import (
18 BodyNotHttplibCompatible
,
29 from .packages
import six
30 from .util
.response
import is_fp_closed
, is_response_to_head
32 log
= logging
.getLogger(__name__
)
35 class DeflateDecoder(object):
37 self
._first
_try
= True
39 self
._obj
= zlib
.decompressobj()
41 def __getattr__(self
, name
):
42 return getattr(self
._obj
, name
)
44 def decompress(self
, data
):
48 if not self
._first
_try
:
49 return self
._obj
.decompress(data
)
53 decompressed
= self
._obj
.decompress(data
)
55 self
._first
_try
= False
59 self
._first
_try
= False
60 self
._obj
= zlib
.decompressobj(-zlib
.MAX_WBITS
)
62 return self
.decompress(self
._data
)
67 class GzipDecoderState(object):
74 class GzipDecoder(object):
76 self
._obj
= zlib
.decompressobj(16 + zlib
.MAX_WBITS
)
77 self
._state
= GzipDecoderState
.FIRST_MEMBER
79 def __getattr__(self
, name
):
80 return getattr(self
._obj
, name
)
82 def decompress(self
, data
):
84 if self
._state
== GzipDecoderState
.SWALLOW_DATA
or not data
:
88 ret
+= self
._obj
.decompress(data
)
90 previous_state
= self
._state
91 # Ignore data after the first error
92 self
._state
= GzipDecoderState
.SWALLOW_DATA
93 if previous_state
== GzipDecoderState
.OTHER_MEMBERS
:
94 # Allow trailing garbage acceptable in other gzip clients
97 data
= self
._obj
.unused_data
100 self
._state
= GzipDecoderState
.OTHER_MEMBERS
101 self
._obj
= zlib
.decompressobj(16 + zlib
.MAX_WBITS
)
104 if brotli
is not None:
106 class BrotliDecoder(object):
107 # Supports both 'brotlipy' and 'Brotli' packages
108 # since they share an import name. The top branches
109 # are for 'brotlipy' and bottom branches for 'Brotli'
111 self
._obj
= brotli
.Decompressor()
112 if hasattr(self
._obj
, "decompress"):
113 self
.decompress
= self
._obj
.decompress
115 self
.decompress
= self
._obj
.process
118 if hasattr(self
._obj
, "flush"):
119 return self
._obj
.flush()
123 class MultiDecoder(object):
126 If one or more encodings have been applied to a representation, the
127 sender that applied the encodings MUST generate a Content-Encoding
128 header field that lists the content codings in the order in which
132 def __init__(self
, modes
):
133 self
._decoders
= [_get_decoder(m
.strip()) for m
in modes
.split(",")]
136 return self
._decoders
[0].flush()
138 def decompress(self
, data
):
139 for d
in reversed(self
._decoders
):
140 data
= d
.decompress(data
)
144 def _get_decoder(mode
):
146 return MultiDecoder(mode
)
151 if brotli
is not None and mode
== "br":
152 return BrotliDecoder()
154 return DeflateDecoder()
157 class HTTPResponse(io
.IOBase
):
159 HTTP Response container.
161 Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
162 loaded and decoded on-demand when the ``data`` property is accessed. This
163 class is also compatible with the Python standard library's :mod:`io`
164 module, and can hence be treated as a readable object in the context of that
167 Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
169 :param preload_content:
170 If True, the response's body will be preloaded during construction.
172 :param decode_content:
173 If True, will attempt to decode the body based on the
174 'content-encoding' header.
176 :param original_response:
177 When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
178 object, it's convenient to include the original for debug purposes. It's
182 The retries contains the last :class:`~urllib3.util.retry.Retry` that
183 was used during the request.
185 :param enforce_content_length:
186 Enforce content length checking. Body returned by server must match
187 value of Content-Length header, if present. Otherwise, raise error.
190 CONTENT_DECODERS
= ["gzip", "deflate"]
191 if brotli
is not None:
192 CONTENT_DECODERS
+= ["br"]
193 REDIRECT_STATUSES
= [301, 302, 303, 307, 308]
203 preload_content
=True,
205 original_response
=None,
210 enforce_content_length
=False,
216 if isinstance(headers
, HTTPHeaderDict
):
217 self
.headers
= headers
219 self
.headers
= HTTPHeaderDict(headers
)
221 self
.version
= version
224 self
.decode_content
= decode_content
225 self
.retries
= retries
226 self
.enforce_content_length
= enforce_content_length
227 self
.auto_close
= auto_close
232 self
._original
_response
= original_response
233 self
._fp
_bytes
_read
= 0
235 self
._request
_url
= request_url
237 if body
and isinstance(body
, (six
.string_types
, bytes)):
241 self
._connection
= connection
243 if hasattr(body
, "read"):
246 # Are we using the chunked-style of transfer encoding?
248 self
.chunk_left
= None
249 tr_enc
= self
.headers
.get("transfer-encoding", "").lower()
250 # Don't incur the penalty of creating a list and then discarding it
251 encodings
= (enc
.strip() for enc
in tr_enc
.split(","))
252 if "chunked" in encodings
:
255 # Determine length of response
256 self
.length_remaining
= self
._init
_length
(request_method
)
258 # If requested, preload the body.
259 if preload_content
and not self
._body
:
260 self
._body
= self
.read(decode_content
=decode_content
)
262 def get_redirect_location(self
):
264 Should we redirect and where to?
266 :returns: Truthy redirect location string if we got a redirect status
267 code and valid location. ``None`` if redirect status and no
268 location. ``False`` if not a redirect status code.
270 if self
.status
in self
.REDIRECT_STATUSES
:
271 return self
.headers
.get("location")
275 def release_conn(self
):
276 if not self
._pool
or not self
._connection
:
279 self
._pool
._put
_conn
(self
._connection
)
280 self
._connection
= None
282 def drain_conn(self
):
284 Read and discard any remaining HTTP response data in the response connection.
286 Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
290 except (HTTPError
, SocketError
, BaseSSLError
, HTTPException
):
295 # For backwards-compat with earlier urllib3 0.4 and earlier.
300 return self
.read(cache_content
=True)
303 def connection(self
):
304 return self
._connection
307 return is_fp_closed(self
._fp
)
311 Obtain the number of bytes pulled over the wire so far. May differ from
312 the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``
313 if bytes are encoded on the wire (e.g, compressed).
315 return self
._fp
_bytes
_read
317 def _init_length(self
, request_method
):
319 Set initial length value for Response content if available.
321 length
= self
.headers
.get("content-length")
323 if length
is not None:
325 # This Response will fail with an IncompleteRead if it can't be
326 # received as chunked. This method falls back to attempt reading
327 # the response before raising an exception.
329 "Received response with both Content-Length and "
330 "Transfer-Encoding set. This is expressly forbidden "
331 "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
332 "attempting to process response as Transfer-Encoding: "
338 # RFC 7230 section 3.3.2 specifies multiple content lengths can
339 # be sent in a single Content-Length header
340 # (e.g. Content-Length: 42, 42). This line ensures the values
341 # are all valid ints and that as long as the `set` length is 1,
342 # all values are the same. Otherwise, the header is invalid.
343 lengths
= set([int(val
) for val
in length
.split(",")])
346 "Content-Length contained multiple "
347 "unmatching values (%s)" % length
349 length
= lengths
.pop()
356 # Convert status to int for comparison
357 # In some cases, httplib returns a status of "_UNKNOWN"
359 status
= int(self
.status
)
363 # Check for responses that shouldn't include a body
364 if status
in (204, 304) or 100 <= status
< 200 or request_method
== "HEAD":
369 def _init_decoder(self
):
371 Set-up the _decoder attribute if necessary.
373 # Note: content-encoding value should be case-insensitive, per RFC 7230
375 content_encoding
= self
.headers
.get("content-encoding", "").lower()
376 if self
._decoder
is None:
377 if content_encoding
in self
.CONTENT_DECODERS
:
378 self
._decoder
= _get_decoder(content_encoding
)
379 elif "," in content_encoding
:
382 for e
in content_encoding
.split(",")
383 if e
.strip() in self
.CONTENT_DECODERS
386 self
._decoder
= _get_decoder(content_encoding
)
388 DECODER_ERROR_CLASSES
= (IOError, zlib
.error
)
389 if brotli
is not None:
390 DECODER_ERROR_CLASSES
+= (brotli
.error
,)
392 def _decode(self
, data
, decode_content
, flush_decoder
):
394 Decode the data passed in and potentially flush the decoder.
396 if not decode_content
:
401 data
= self
._decoder
.decompress(data
)
402 except self
.DECODER_ERROR_CLASSES
as e
:
403 content_encoding
= self
.headers
.get("content-encoding", "").lower()
405 "Received response with content-encoding: %s, but "
406 "failed to decode it." % content_encoding
,
410 data
+= self
._flush
_decoder
()
414 def _flush_decoder(self
):
416 Flushes the decoder. Should only be called if the decoder is actually
420 buf
= self
._decoder
.decompress(b
"")
421 return buf
+ self
._decoder
.flush()
426 def _error_catcher(self
):
428 Catch low-level python exceptions, instead re-raising urllib3
429 variants, so that low-level exceptions are not leaked in the
432 On exit, release the connection back to the pool.
440 except SocketTimeout
:
441 # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
442 # there is yet no clean way to get at it from this context.
443 raise ReadTimeoutError(self
._pool
, None, "Read timed out.")
445 except BaseSSLError
as e
:
446 # FIXME: Is there a better way to differentiate between SSLErrors?
447 if "read operation timed out" not in str(e
):
448 # SSL errors related to framing/MAC get wrapped and reraised here
451 raise ReadTimeoutError(self
._pool
, None, "Read timed out.")
453 except (HTTPException
, SocketError
) as e
:
454 # This includes IncompleteRead.
455 raise ProtocolError("Connection broken: %r" % e
, e
)
457 # If no exception is thrown, we should avoid cleaning up
461 # If we didn't terminate cleanly, we need to throw away our
464 # The response may not be closed but we're not going to use it
465 # anymore so close it now to ensure that the connection is
466 # released back to the pool.
467 if self
._original
_response
:
468 self
._original
_response
.close()
470 # Closing the response may not actually be sufficient to close
471 # everything, so if we have a hold of the connection close that
474 self
._connection
.close()
476 # If we hold the original response but it's closed now, we should
477 # return the connection back to the pool.
478 if self
._original
_response
and self
._original
_response
.isclosed():
481 def _fp_read(self
, amt
):
483 Read a response with the thought that reading the number of bytes
484 larger than can fit in a 32-bit int at a time via SSL in some
485 known cases leads to an overflow error that has to be prevented
486 if `amt` or `self.length_remaining` indicate that a problem may
490 * 3.8 <= CPython < 3.9.7 because of a bug
491 https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900.
492 * urllib3 injected with pyOpenSSL-backed SSL-support.
493 * CPython < 3.10 only when `amt` does not fit 32-bit int.
496 c_int_max
= 2 ** 31 - 1
499 (amt
and amt
> c_int_max
)
500 or (self
.length_remaining
and self
.length_remaining
> c_int_max
)
502 and not util
.IS_SECURETRANSPORT
503 and (util
.IS_PYOPENSSL
or sys
.version_info
< (3, 10))
505 buffer = io
.BytesIO()
506 # Besides `max_chunk_amt` being a maximum chunk size, it
507 # affects memory overhead of reading a response by this
509 # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
510 # chunk size that does not lead to an overflow error, but
511 # 256 MiB is a compromise.
512 max_chunk_amt
= 2 ** 28
513 while amt
is None or amt
!= 0:
515 chunk_amt
= min(amt
, max_chunk_amt
)
518 chunk_amt
= max_chunk_amt
519 data
= self
._fp
.read(chunk_amt
)
523 del data
# to reduce peak memory usage by `max_chunk_amt`.
524 return buffer.getvalue()
526 # StringIO doesn't like amt=None
527 return self
._fp
.read(amt
) if amt
is not None else self
._fp
.read()
529 def read(self
, amt
=None, decode_content
=None, cache_content
=False):
531 Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
532 parameters: ``decode_content`` and ``cache_content``.
535 How much of the content to read. If specified, caching is skipped
536 because it doesn't make sense to cache partial content as the full
539 :param decode_content:
540 If True, will attempt to decode the body based on the
541 'content-encoding' header.
543 :param cache_content:
544 If True, will save the returned data such that the same result is
545 returned despite of the state of the underlying file object. This
546 is useful if you want the ``.data`` property to continue working
547 after having ``.read()`` the file object. (Overridden if ``amt`` is
551 if decode_content
is None:
552 decode_content
= self
.decode_content
557 flush_decoder
= False
558 fp_closed
= getattr(self
._fp
, "closed", False)
560 with self
._error
_catcher
():
561 data
= self
._fp
_read
(amt
) if not fp_closed
else b
""
565 cache_content
= False
567 amt
!= 0 and not data
568 ): # Platform-specific: Buggy versions of Python.
569 # Close the connection when no data is returned
571 # This is redundant to what httplib/http.client _should_
572 # already do. However, versions of python released before
573 # December 15, 2012 (http://bugs.python.org/issue16298) do
574 # not properly close the connection in all cases. There is
575 # no harm in redundantly calling close.
578 if self
.enforce_content_length
and self
.length_remaining
not in (
582 # This is an edge case that httplib failed to cover due
583 # to concerns of backward compatibility. We're
584 # addressing it here to make sure IncompleteRead is
585 # raised during streaming, so all calls with incorrect
586 # Content-Length are caught.
587 raise IncompleteRead(self
._fp
_bytes
_read
, self
.length_remaining
)
590 self
._fp
_bytes
_read
+= len(data
)
591 if self
.length_remaining
is not None:
592 self
.length_remaining
-= len(data
)
594 data
= self
._decode
(data
, decode_content
, flush_decoder
)
601 def stream(self
, amt
=2 ** 16, decode_content
=None):
603 A generator wrapper for the read() method. A call will block until
604 ``amt`` bytes have been read from the connection or until the
605 connection is closed.
608 How much of the content to read. The generator will return up to
609 much data per iteration, but may return less. This is particularly
610 likely when using compressed data. However, the empty string will
613 :param decode_content:
614 If True, will attempt to decode the body based on the
615 'content-encoding' header.
617 if self
.chunked
and self
.supports_chunked_reads():
618 for line
in self
.read_chunked(amt
, decode_content
=decode_content
):
621 while not is_fp_closed(self
._fp
):
622 data
= self
.read(amt
=amt
, decode_content
=decode_content
)
628 def from_httplib(ResponseCls
, r
, **response_kw
):
630 Given an :class:`http.client.HTTPResponse` instance ``r``, return a
631 corresponding :class:`urllib3.response.HTTPResponse` object.
633 Remaining parameters are passed to the HTTPResponse constructor, along
634 with ``original_response=r``.
638 if not isinstance(headers
, HTTPHeaderDict
):
641 headers
= HTTPHeaderDict
.from_httplib(headers
)
643 headers
= HTTPHeaderDict(headers
.items())
645 # HTTPResponse objects in Python 3 don't have a .strict attribute
646 strict
= getattr(r
, "strict", 0)
659 # Backwards-compatibility methods for http.client.HTTPResponse
660 def getheaders(self
):
662 "HTTPResponse.getheaders() is deprecated and will be removed "
663 "in urllib3 v2.1.0. Instead access HTTPResponse.headers directly.",
664 category
=DeprecationWarning,
669 def getheader(self
, name
, default
=None):
671 "HTTPResponse.getheader() is deprecated and will be removed "
672 "in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).",
673 category
=DeprecationWarning,
676 return self
.headers
.get(name
, default
)
678 # Backwards compatibility for http.cookiejar
682 # Overrides from io.IOBase
688 self
._connection
.close()
690 if not self
.auto_close
:
691 io
.IOBase
.close(self
)
695 if not self
.auto_close
:
696 return io
.IOBase
.closed
.__get
__(self
)
697 elif self
._fp
is None:
699 elif hasattr(self
._fp
, "isclosed"):
700 return self
._fp
.isclosed()
701 elif hasattr(self
._fp
, "closed"):
702 return self
._fp
.closed
708 raise IOError("HTTPResponse has no file to get a fileno from")
709 elif hasattr(self
._fp
, "fileno"):
710 return self
._fp
.fileno()
713 "The file-like object this HTTPResponse is wrapped "
714 "around has no file descriptor"
720 and hasattr(self
._fp
, "flush")
721 and not getattr(self
._fp
, "closed", False)
723 return self
._fp
.flush()
726 # This method is required for `io` module compatibility.
729 def readinto(self
, b
):
730 # This method is required for `io` module compatibility.
731 temp
= self
.read(len(b
))
735 b
[: len(temp
)] = temp
738 def supports_chunked_reads(self
):
740 Checks if the underlying file-like object looks like a
741 :class:`http.client.HTTPResponse` object. We do this by testing for
742 the fp attribute. If it is present we assume it returns raw chunks as
743 processed by read_chunked().
745 return hasattr(self
._fp
, "fp")
747 def _update_chunk_length(self
):
748 # First, we'll figure out length of a chunk and then
749 # we'll try to read it from socket.
750 if self
.chunk_left
is not None:
752 line
= self
._fp
.fp
.readline()
753 line
= line
.split(b
";", 1)[0]
755 self
.chunk_left
= int(line
, 16)
757 # Invalid chunked protocol response, abort.
759 raise InvalidChunkLength(self
, line
)
761 def _handle_chunk(self
, amt
):
762 returned_chunk
= None
764 chunk
= self
._fp
._safe
_read
(self
.chunk_left
)
765 returned_chunk
= chunk
766 self
._fp
._safe
_read
(2) # Toss the CRLF at the end of the chunk.
767 self
.chunk_left
= None
768 elif amt
< self
.chunk_left
:
769 value
= self
._fp
._safe
_read
(amt
)
770 self
.chunk_left
= self
.chunk_left
- amt
771 returned_chunk
= value
772 elif amt
== self
.chunk_left
:
773 value
= self
._fp
._safe
_read
(amt
)
774 self
._fp
._safe
_read
(2) # Toss the CRLF at the end of the chunk.
775 self
.chunk_left
= None
776 returned_chunk
= value
777 else: # amt > self.chunk_left
778 returned_chunk
= self
._fp
._safe
_read
(self
.chunk_left
)
779 self
._fp
._safe
_read
(2) # Toss the CRLF at the end of the chunk.
780 self
.chunk_left
= None
781 return returned_chunk
783 def read_chunked(self
, amt
=None, decode_content
=None):
785 Similar to :meth:`HTTPResponse.read`, but with an additional
786 parameter: ``decode_content``.
789 How much of the content to read. If specified, caching is skipped
790 because it doesn't make sense to cache partial content as the full
793 :param decode_content:
794 If True, will attempt to decode the body based on the
795 'content-encoding' header.
798 # FIXME: Rewrite this method and make it a class with a better structured logic.
800 raise ResponseNotChunked(
801 "Response is not chunked. "
802 "Header 'transfer-encoding: chunked' is missing."
804 if not self
.supports_chunked_reads():
805 raise BodyNotHttplibCompatible(
806 "Body should be http.client.HTTPResponse like. "
807 "It should have have an fp attribute which returns raw chunks."
810 with self
._error
_catcher
():
811 # Don't bother reading the body of a HEAD request.
812 if self
._original
_response
and is_response_to_head(self
._original
_response
):
813 self
._original
_response
.close()
816 # If a response is already read and closed
817 # then return immediately.
818 if self
._fp
.fp
is None:
822 self
._update
_chunk
_length
()
823 if self
.chunk_left
== 0:
825 chunk
= self
._handle
_chunk
(amt
)
826 decoded
= self
._decode
(
827 chunk
, decode_content
=decode_content
, flush_decoder
=False
833 # On CPython and PyPy, we should never need to flush the
834 # decoder. However, on Jython we *might* need to, so
835 # lets defensively do it anyway.
836 decoded
= self
._flush
_decoder
()
837 if decoded
: # Platform-specific: Jython.
840 # Chunk content ends with \r\n: discard it.
842 line
= self
._fp
.fp
.readline()
844 # Some sites may not end with '\r\n'.
849 # We read everything; close the "file".
850 if self
._original
_response
:
851 self
._original
_response
.close()
855 Returns the URL that was the source of this response.
856 If the request that generated this response redirected, this method
857 will return the final redirect location.
859 if self
.retries
is not None and len(self
.retries
.history
):
860 return self
.retries
.history
[-1].redirect_location
862 return self
._request
_url
866 for chunk
in self
.stream(decode_content
=True):
868 chunk
= chunk
.split(b
"\n")
869 yield b
"".join(buffer) + chunk
[0] + b
"\n"
870 for x
in chunk
[1:-1]:
879 yield b
"".join(buffer)