| 1 | # SPDX-License-Identifier: MIT |
| 2 | from __future__ import absolute_import |
| 3 | from ..packages.six.moves import http_client as httplib |
| 4 | |
| 5 | from ..exceptions import HeaderParsingError |
| 6 | |
| 7 | |
| 8 | def is_fp_closed(obj): |
| 9 | """ |
| 10 | Checks whether a given file-like object is closed. |
| 11 | |
| 12 | :param obj: |
| 13 | The file-like object to check. |
| 14 | """ |
| 15 | |
| 16 | try: |
| 17 | # Check `isclosed()` first, in case Python3 doesn't set `closed`. |
| 18 | # GH Issue #928 |
| 19 | return obj.isclosed() |
| 20 | except AttributeError: |
| 21 | pass |
| 22 | |
| 23 | try: |
| 24 | # Check via the official file-like-object way. |
| 25 | return obj.closed |
| 26 | except AttributeError: |
| 27 | pass |
| 28 | |
| 29 | try: |
| 30 | # Check if the object is a container for another file-like object that |
| 31 | # gets released on exhaustion (e.g. HTTPResponse). |
| 32 | return obj.fp is None |
| 33 | except AttributeError: |
| 34 | pass |
| 35 | |
| 36 | raise ValueError("Unable to determine whether fp is closed.") |
| 37 | |
| 38 | |
| 39 | def assert_header_parsing(headers): |
| 40 | """ |
| 41 | Asserts whether all headers have been successfully parsed. |
| 42 | Extracts encountered errors from the result of parsing headers. |
| 43 | |
| 44 | Only works on Python 3. |
| 45 | |
| 46 | :param headers: Headers to verify. |
| 47 | :type headers: `httplib.HTTPMessage`. |
| 48 | |
| 49 | :raises urllib3.exceptions.HeaderParsingError: |
| 50 | If parsing errors are found. |
| 51 | """ |
| 52 | |
| 53 | # This will fail silently if we pass in the wrong kind of parameter. |
| 54 | # To make debugging easier add an explicit check. |
| 55 | if not isinstance(headers, httplib.HTTPMessage): |
| 56 | raise TypeError('expected httplib.Message, got {0}.'.format( |
| 57 | type(headers))) |
| 58 | |
| 59 | defects = getattr(headers, 'defects', None) |
| 60 | get_payload = getattr(headers, 'get_payload', None) |
| 61 | |
| 62 | unparsed_data = None |
| 63 | if get_payload: # Platform-specific: Python 3. |
| 64 | unparsed_data = get_payload() |
| 65 | |
| 66 | if defects or unparsed_data: |
| 67 | raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) |
| 68 | |
| 69 | |
| 70 | def is_response_to_head(response): |
| 71 | """ |
| 72 | Checks whether the request of a response has been a HEAD-request. |
| 73 | Handles the quirks of AppEngine. |
| 74 | |
| 75 | :param conn: |
| 76 | :type conn: :class:`httplib.HTTPResponse` |
| 77 | """ |
| 78 | # FIXME: Can we do this somehow without accessing private httplib _method? |
| 79 | method = response._method |
| 80 | if isinstance(method, int): # Platform-specific: Appengine |
| 81 | return method == 3 |
| 82 | return method.upper() == 'HEAD' |