| 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: |
| |
| |
| return obj.isclosed() |
| except AttributeError: |
| pass |
|
|
| try: |
| |
| return obj.closed |
| except AttributeError: |
| pass |
|
|
| try: |
| |
| |
| return obj.fp is None |
| 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. |
| """ |
|
|
| |
| |
| if not isinstance(headers, httplib.HTTPMessage): |
| raise TypeError(f"expected httplib.Message, got {type(headers)}.") |
|
|
| unparsed_data = None |
|
|
| |
| |
| if not headers.is_multipart(): |
| payload = headers.get_payload() |
|
|
| if isinstance(payload, (bytes, str)): |
| unparsed_data = payload |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| 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. |
| """ |
| |
| method_str = response._method |
| return method_str.upper() == "HEAD" |
|
|