1 from __future__
import absolute_import
3 from email
.errors
import MultipartInvariantViolationDefect
, StartBoundaryNotFoundDefect
5 from ..exceptions
import HeaderParsingError
6 from ..packages
.six
.moves
import http_client
as httplib
11 Checks whether a given file-like object is closed.
14 The file-like object to check.
18 # Check `isclosed()` first, in case Python3 doesn't set `closed`.
21 except AttributeError:
25 # Check via the official file-like-object way.
27 except AttributeError:
31 # Check if the object is a container for another file-like object that
32 # gets released on exhaustion (e.g. HTTPResponse).
34 except AttributeError:
37 raise ValueError("Unable to determine whether fp is closed.")
40 def assert_header_parsing(headers
):
42 Asserts whether all headers have been successfully parsed.
43 Extracts encountered errors from the result of parsing headers.
45 Only works on Python 3.
47 :param http.client.HTTPMessage headers: Headers to verify.
49 :raises urllib3.exceptions.HeaderParsingError:
50 If parsing errors are found.
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(type(headers
)))
58 defects
= getattr(headers
, "defects", None)
59 get_payload
= getattr(headers
, "get_payload", None)
63 # get_payload is actually email.message.Message.get_payload;
64 # we're only interested in the result if it's not a multipart message
65 if not headers
.is_multipart():
66 payload
= get_payload()
68 if isinstance(payload
, (bytes, str)):
69 unparsed_data
= payload
71 # httplib is assuming a response body is available
72 # when parsing headers even when httplib only sends
73 # header data to parse_headers() This results in
74 # defects on multipart responses in particular.
75 # See: https://github.com/urllib3/urllib3/issues/800
77 # So we ignore the following defects:
78 # - StartBoundaryNotFoundDefect:
79 # The claimed start boundary was never found.
80 # - MultipartInvariantViolationDefect:
81 # A message claimed to be a multipart but no subparts were found.
86 defect
, (StartBoundaryNotFoundDefect
, MultipartInvariantViolationDefect
)
90 if defects
or unparsed_data
:
91 raise HeaderParsingError(defects
=defects
, unparsed_data
=unparsed_data
)
94 def is_response_to_head(response
):
96 Checks whether the request of a response has been a HEAD-request.
97 Handles the quirks of AppEngine.
99 :param http.client.HTTPResponse response:
100 Response to check if the originating request
101 used 'HEAD' as a method.
103 # FIXME: Can we do this somehow without accessing private httplib _method?
104 method
= response
._method
105 if isinstance(method
, int): # Platform-specific: Appengine
107 return method
.upper() == "HEAD"