Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions requests_toolbelt/adapters/host_header_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,29 @@ class HostHeaderSSLAdapter(HTTPAdapter):
A HTTPS Adapter for Python Requests that sets the hostname for certificate
verification based on the Host header.

This allows requesting the IP address directly via HTTPS without getting
This allows requesting the IP address or CNAME directly via HTTPS without getting
a "hostname doesn't match" exception.

Example usage:

>>> s.mount('https://', HostHeaderSSLAdapter())
>>> s.get("https://93.184.216.34", headers={"Host": "example.org"})

>>> s.get("https://93.184.216.34/", headers={"Host": "example.org"})
>>> s.get("https://cname.example.org/", headers={"Host": "example.org"})
"""

def send(self, request, **kwargs):
# HTTP headers are case-insensitive (RFC 7230)
host_header = None
for header in request.headers:
if header.lower() == "host":
host_header = request.headers[header]
break
# request.headers is a CaseInsensitiveDict
host_header = request.headers.get('Host',None)

connection_pool_kwargs = self.poolmanager.connection_pool_kw

if host_header:
if request.url[:5] == "https" and host_header:
connection_pool_kwargs["assert_hostname"] = host_header
elif "assert_hostname" in connection_pool_kwargs:
connection_pool_kwargs["server_hostname"] = host_header # SNI
else:
# an assert_hostname from a previous request may have been left
connection_pool_kwargs.pop("assert_hostname", None)
connection_pool_kwargs.pop("server_hostname", None) # SNI

return super(HostHeaderSSLAdapter, self).send(request, **kwargs)