diff urllib3/util/response.py @ 7:5eb2d5e3bf22

planemo upload for repository https://toolrepo.galaxytrakr.org/view/jpayne/bioproject_to_srr_2/556cac4fb538
author jpayne
date Sun, 05 May 2024 23:32:17 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/urllib3/util/response.py	Sun May 05 23:32:17 2024 -0400
@@ -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"