aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/urllib3/util/response.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/urllib3/util/response.py')
-rw-r--r--.venv/lib/python3.12/site-packages/urllib3/util/response.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/urllib3/util/response.py b/.venv/lib/python3.12/site-packages/urllib3/util/response.py
new file mode 100644
index 00000000..0f457869
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/urllib3/util/response.py
@@ -0,0 +1,101 @@
+from __future__ import annotations
+
+import http.client as httplib
+from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
+
+from ..exceptions import HeaderParsingError
+
+
+def is_fp_closed(obj: object) -> bool:
+ """
+ Checks whether a given file-like object is closed.
+
+ :param obj:
+ The file-like object to check.
+ """
+
+ try:
+ # Check `isclosed()` first, in case Python3 doesn't set `closed`.
+ # GH Issue #928
+ return obj.isclosed() # type: ignore[no-any-return, attr-defined]
+ except AttributeError:
+ pass
+
+ try:
+ # Check via the official file-like-object way.
+ return obj.closed # type: ignore[no-any-return, attr-defined]
+ except AttributeError:
+ pass
+
+ try:
+ # Check if the object is a container for another file-like object that
+ # gets released on exhaustion (e.g. HTTPResponse).
+ return obj.fp is None # type: ignore[attr-defined]
+ except AttributeError:
+ pass
+
+ raise ValueError("Unable to determine whether fp is closed.")
+
+
+def assert_header_parsing(headers: httplib.HTTPMessage) -> None:
+ """
+ Asserts whether all headers have been successfully parsed.
+ Extracts encountered errors from the result of parsing headers.
+
+ Only works on Python 3.
+
+ :param http.client.HTTPMessage headers: Headers to verify.
+
+ :raises urllib3.exceptions.HeaderParsingError:
+ If parsing errors are found.
+ """
+
+ # This will fail silently if we pass in the wrong kind of parameter.
+ # To make debugging easier add an explicit check.
+ if not isinstance(headers, httplib.HTTPMessage):
+ raise TypeError(f"expected httplib.Message, got {type(headers)}.")
+
+ unparsed_data = None
+
+ # get_payload is actually email.message.Message.get_payload;
+ # we're only interested in the result if it's not a multipart message
+ if not headers.is_multipart():
+ payload = headers.get_payload()
+
+ if isinstance(payload, (bytes, str)):
+ unparsed_data = payload
+
+ # httplib is assuming a response body is available
+ # when parsing headers even when httplib only sends
+ # header data to parse_headers() This results in
+ # defects on multipart responses in particular.
+ # See: https://github.com/urllib3/urllib3/issues/800
+
+ # So we ignore the following defects:
+ # - StartBoundaryNotFoundDefect:
+ # The claimed start boundary was never found.
+ # - MultipartInvariantViolationDefect:
+ # A message claimed to be a multipart but no subparts were found.
+ defects = [
+ defect
+ for defect in headers.defects
+ if not isinstance(
+ defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
+ )
+ ]
+
+ if defects or unparsed_data:
+ raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
+
+
+def is_response_to_head(response: httplib.HTTPResponse) -> bool:
+ """
+ Checks whether the request of a response has been a HEAD-request.
+
+ :param http.client.HTTPResponse response:
+ Response to check if the originating request
+ used 'HEAD' as a method.
+ """
+ # FIXME: Can we do this somehow without accessing private httplib _method?
+ method_str = response._method # type: str # type: ignore[attr-defined]
+ return method_str.upper() == "HEAD"