Skip to content

Commit f0b234e

Browse files
authored
gh-94172: urllib.request avoids deprecated check_hostname (#94193)
The urllib.request no longer uses the deprecated check_hostname parameter of the http.client module. Add private http.client._create_https_context() helper to http.client, used by urllib.request. Remove the now redundant check on check_hostname and verify_mode in http.client: the SSLContext.check_hostname setter already implements the check.
1 parent e69306f commit f0b234e

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

Lib/http/client.py

+17-15
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,20 @@ def getcode(self):
786786
'''
787787
return self.status
788788

789+
790+
def _create_https_context(http_version):
791+
# Function also used by urllib.request to be able to set the check_hostname
792+
# attribute on a context object.
793+
context = ssl._create_default_https_context()
794+
# send ALPN extension to indicate HTTP/1.1 protocol
795+
if http_version == 11:
796+
context.set_alpn_protocols(['http/1.1'])
797+
# enable PHA for TLS 1.3 connections if available
798+
if context.post_handshake_auth is not None:
799+
context.post_handshake_auth = True
800+
return context
801+
802+
789803
class HTTPConnection:
790804

791805
_http_vsn = 11
@@ -1418,28 +1432,16 @@ def __init__(self, host, port=None, key_file=None, cert_file=None,
14181432
self.key_file = key_file
14191433
self.cert_file = cert_file
14201434
if context is None:
1421-
context = ssl._create_default_https_context()
1422-
# send ALPN extension to indicate HTTP/1.1 protocol
1423-
if self._http_vsn == 11:
1424-
context.set_alpn_protocols(['http/1.1'])
1425-
# enable PHA for TLS 1.3 connections if available
1426-
if context.post_handshake_auth is not None:
1427-
context.post_handshake_auth = True
1428-
will_verify = context.verify_mode != ssl.CERT_NONE
1429-
if check_hostname is None:
1430-
check_hostname = context.check_hostname
1431-
if check_hostname and not will_verify:
1432-
raise ValueError("check_hostname needs a SSL context with "
1433-
"either CERT_OPTIONAL or CERT_REQUIRED")
1435+
context = _create_https_context(self._http_vsn)
1436+
if check_hostname is not None:
1437+
context.check_hostname = check_hostname
14341438
if key_file or cert_file:
14351439
context.load_cert_chain(cert_file, key_file)
14361440
# cert and key file means the user wants to authenticate.
14371441
# enable TLS 1.3 PHA implicitly even for custom contexts.
14381442
if context.post_handshake_auth is not None:
14391443
context.post_handshake_auth = True
14401444
self._context = context
1441-
if check_hostname is not None:
1442-
self._context.check_hostname = check_hostname
14431445

14441446
def connect(self):
14451447
"Connect to a host on a given (SSL) port."

Lib/urllib/request.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1383,12 +1383,16 @@ class HTTPSHandler(AbstractHTTPHandler):
13831383

13841384
def __init__(self, debuglevel=0, context=None, check_hostname=None):
13851385
AbstractHTTPHandler.__init__(self, debuglevel)
1386+
if context is None:
1387+
http_version = http.client.HTTPSConnection._http_vsn
1388+
context = http.client._create_https_context(http_version)
1389+
if check_hostname is not None:
1390+
context.check_hostname = check_hostname
13861391
self._context = context
1387-
self._check_hostname = check_hostname
13881392

13891393
def https_open(self, req):
13901394
return self.do_open(http.client.HTTPSConnection, req,
1391-
context=self._context, check_hostname=self._check_hostname)
1395+
context=self._context)
13921396

13931397
https_request = AbstractHTTPHandler.do_request_
13941398

0 commit comments

Comments
 (0)