host_header_ssl.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. # -*- coding: utf-8 -*-
  2. """
  3. requests_toolbelt.adapters.host_header_ssl
  4. ==========================================
  5. This file contains an implementation of the HostHeaderSSLAdapter.
  6. """
  7. from requests.adapters import HTTPAdapter
  8. class HostHeaderSSLAdapter(HTTPAdapter):
  9. """
  10. A HTTPS Adapter for Python Requests that sets the hostname for certificate
  11. verification based on the Host header.
  12. This allows requesting the IP address directly via HTTPS without getting
  13. a "hostname doesn't match" exception.
  14. Example usage:
  15. >>> s.mount('https://', HostHeaderSSLAdapter())
  16. >>> s.get("https://93.184.216.34", headers={"Host": "example.org"})
  17. """
  18. def send(self, request, **kwargs):
  19. # HTTP headers are case-insensitive (RFC 7230)
  20. host_header = None
  21. for header in request.headers:
  22. if header.lower() == "host":
  23. host_header = request.headers[header]
  24. break
  25. connection_pool_kwargs = self.poolmanager.connection_pool_kw
  26. if host_header:
  27. connection_pool_kwargs["assert_hostname"] = host_header
  28. elif "assert_hostname" in connection_pool_kwargs:
  29. # an assert_hostname from a previous request may have been left
  30. connection_pool_kwargs.pop("assert_hostname", None)
  31. return super(HostHeaderSSLAdapter, self).send(request, **kwargs)