mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
Issue #9003: http.client.HTTPSConnection, urllib.request.HTTPSHandler and
urllib.request.urlopen now take optional arguments to allow for server certificate checking, as recommended in public uses of HTTPS.
This commit is contained in:
parent
bd4dacb3f9
commit
803e6d670c
11 changed files with 418 additions and 160 deletions
|
@ -114,11 +114,27 @@ else:
|
|||
__version__ = sys.version[:3]
|
||||
|
||||
_opener = None
|
||||
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
|
||||
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
|
||||
*, cafile=None, capath=None):
|
||||
global _opener
|
||||
if _opener is None:
|
||||
_opener = build_opener()
|
||||
return _opener.open(url, data, timeout)
|
||||
if cafile or capath:
|
||||
if not _have_ssl:
|
||||
raise ValueError('SSL support not available')
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
context.options |= ssl.OP_NO_SSLv2
|
||||
if cafile or capath:
|
||||
context.verify_mode = ssl.CERT_REQUIRED
|
||||
context.load_verify_locations(cafile, capath)
|
||||
check_hostname = True
|
||||
else:
|
||||
check_hostname = False
|
||||
https_handler = HTTPSHandler(context=context, check_hostname=check_hostname)
|
||||
opener = build_opener(https_handler)
|
||||
elif _opener is None:
|
||||
_opener = opener = build_opener()
|
||||
else:
|
||||
opener = _opener
|
||||
return opener.open(url, data, timeout)
|
||||
|
||||
def install_opener(opener):
|
||||
global _opener
|
||||
|
@ -1053,7 +1069,7 @@ class AbstractHTTPHandler(BaseHandler):
|
|||
|
||||
return request
|
||||
|
||||
def do_open(self, http_class, req):
|
||||
def do_open(self, http_class, req, **http_conn_args):
|
||||
"""Return an HTTPResponse object for the request, using http_class.
|
||||
|
||||
http_class must implement the HTTPConnection API from http.client.
|
||||
|
@ -1062,7 +1078,8 @@ class AbstractHTTPHandler(BaseHandler):
|
|||
if not host:
|
||||
raise URLError('no host given')
|
||||
|
||||
h = http_class(host, timeout=req.timeout) # will parse host:port
|
||||
# will parse host:port
|
||||
h = http_class(host, timeout=req.timeout, **http_conn_args)
|
||||
|
||||
headers = dict(req.unredirected_hdrs)
|
||||
headers.update(dict((k, v) for k, v in req.headers.items()
|
||||
|
@ -1114,10 +1131,18 @@ class HTTPHandler(AbstractHTTPHandler):
|
|||
http_request = AbstractHTTPHandler.do_request_
|
||||
|
||||
if hasattr(http.client, 'HTTPSConnection'):
|
||||
import ssl
|
||||
|
||||
class HTTPSHandler(AbstractHTTPHandler):
|
||||
|
||||
def __init__(self, debuglevel=0, context=None, check_hostname=None):
|
||||
AbstractHTTPHandler.__init__(self, debuglevel)
|
||||
self._context = context
|
||||
self._check_hostname = check_hostname
|
||||
|
||||
def https_open(self, req):
|
||||
return self.do_open(http.client.HTTPSConnection, req)
|
||||
return self.do_open(http.client.HTTPSConnection, req,
|
||||
context=self._context, check_hostname=self._check_hostname)
|
||||
|
||||
https_request = AbstractHTTPHandler.do_request_
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue