response.py 2.3 KB

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