summaryrefslogtreecommitdiffstats
path: root/Lib/httplib.py
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2014-11-23 17:42:45 (GMT)
committerBenjamin Peterson <benjamin@python.org>2014-11-23 17:42:45 (GMT)
commitfcfb18ee2b754368ff005a3fec8a9fe7930ccf7d (patch)
treed0ec3069e6f10073b55fca4ebf710a8da6123b1f /Lib/httplib.py
parent5f6b89bda3cc9797186c567b6be5c6d8feedb3ec (diff)
downloadcpython-fcfb18ee2b754368ff005a3fec8a9fe7930ccf7d.zip
cpython-fcfb18ee2b754368ff005a3fec8a9fe7930ccf7d.tar.gz
cpython-fcfb18ee2b754368ff005a3fec8a9fe7930ccf7d.tar.bz2
allow passing cert/ssl information to urllib2.urlopen and httplib.HTTPSConnection
This is basically a backport of issues #9003 and #22366.
Diffstat (limited to 'Lib/httplib.py')
-rw-r--r--Lib/httplib.py35
1 files changed, 29 insertions, 6 deletions
diff --git a/Lib/httplib.py b/Lib/httplib.py
index b2f6e5c..db5fa37 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -1187,21 +1187,44 @@ else:
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
- source_address=None):
+ source_address=None, context=None, check_hostname=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
+ if context is None:
+ context = ssl.create_default_context()
+ will_verify = context.verify_mode != ssl.CERT_NONE
+ if check_hostname is None:
+ check_hostname = will_verify
+ elif check_hostname and not will_verify:
+ raise ValueError("check_hostname needs a SSL context with "
+ "either CERT_OPTIONAL or CERT_REQUIRED")
+ if key_file or cert_file:
+ context.load_cert_chain(cert_file, key_file)
+ self._context = context
+ self._check_hostname = check_hostname
def connect(self):
"Connect to a host on a given (SSL) port."
- sock = self._create_connection((self.host, self.port),
- self.timeout, self.source_address)
+ HTTPConnection.connect(self)
+
if self._tunnel_host:
- self.sock = sock
- self._tunnel()
- self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
+ server_hostname = self._tunnel_host
+ else:
+ server_hostname = self.host
+ sni_hostname = server_hostname if ssl.HAS_SNI else None
+
+ self.sock = self._context.wrap_socket(self.sock,
+ server_hostname=sni_hostname)
+ if not self._context.check_hostname and self._check_hostname:
+ try:
+ ssl.match_hostname(self.sock.getpeercert(), server_hostname)
+ except Exception:
+ self.sock.shutdown(socket.SHUT_RDWR)
+ self.sock.close()
+ raise
__all__.append("HTTPSConnection")