(original) (raw)

diff --git a/Lib/httplib.py b/Lib/httplib.py index db5fa37..18031f2 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -1239,14 +1239,15 @@ else: _connection_class = HTTPSConnection def __init__(self, host='', port=None, key_file=None, cert_file=None, - strict=None): + strict=None, context=None): # provide a default host, pass the X509 cert info # urf. compensate for bad input. if port == 0: port = None self._setup(self._connection_class(host, port, key_file, - cert_file, strict)) + cert_file, strict, + context=context)) # we never actually use these for anything, but we keep them # here for compatibility with post-1.5.2 CVS. diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 0032865..5791733 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -9,10 +9,20 @@ import mimetools import tempfile import StringIO +try: + import ssl +except ImportError: + ssl = None + from test import test_support from base64 import b64encode +here = os.path.dirname(__file__) +# Self-signed cert file for self-signed.pythontest.net +CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem') + + def hexescape(char): """Escape char as RFC 2396 specifies""" hex_repr = hex(ord(char))[2:].upper() @@ -278,6 +288,14 @@ Content-Type: text/html; charset=iso-8859-1 self.unfakehttp() +class urlopen_HttpsTests(unittest.TestCase): + def test_context_argument(self): + context = ssl.create_default_context(cafile=CERT_selfsigned_pythontestdotnet) + response = urllib.urlopen("https://self-signed.pythontest.net", context=context) + self.assertIn("Python", response.read()) + + + class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files""" @@ -912,7 +930,7 @@ def test_main(): with warnings.catch_warnings(): warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0", DeprecationWarning) - test_support.run_unittest( + tests = [ urlopen_FileTests, urlopen_HttpTests, urlretrieve_FileTests, @@ -925,7 +943,10 @@ def test_main(): Utility_Tests, URLopener_Tests, #FTPWrapperTests, - ) + ] + if ssl is not None: + tests.append(urlopen_HttpsTests) + test_support.run_unittest(*tests) diff --git a/Lib/urllib.py b/Lib/urllib.py index ac5d797..2408cb8 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -69,15 +69,15 @@ else: # Shortcut for basic usage _urlopener = None -def urlopen(url, data=None, proxies=None): +def urlopen(url, data=None, proxies=None, context=None): """Create a file-like object for the specified URL to read from.""" from warnings import warnpy3k warnpy3k("urllib.urlopen() has been removed in Python 3.0 in " "favor of urllib2.urlopen()", stacklevel=2) global _urlopener - if proxies is not None: - opener = FancyURLopener(proxies=proxies) + if proxies is not None or context is not None: + opener = FancyURLopener(proxies=proxies, context=context) elif not _urlopener: opener = FancyURLopener() _urlopener = opener @@ -87,11 +87,15 @@ def urlopen(url, data=None, proxies=None): return opener.open(url) else: return opener.open(url, data) -def urlretrieve(url, filename=None, reporthook=None, data=None): +def urlretrieve(url, filename=None, reporthook=None, data=None, context=None): global _urlopener - if not _urlopener: - _urlopener = FancyURLopener() - return _urlopener.retrieve(url, filename, reporthook, data) + if context is not None: + opener = FancyURLopener(context=context) + elif not _urlopener: + _urlopener = opener = FancyURLopener() + else: + opener = _urlopener + return opener.retrieve(url, filename, reporthook, data) def urlcleanup(): if _urlopener: _urlopener.cleanup() @@ -126,13 +130,14 @@ class URLopener: version = "Python-urllib/%s" % __version__ # Constructor - def __init__(self, proxies=None, **x509): + def __init__(self, proxies=None, context=None, **x509): if proxies is None: proxies = getproxies() assert hasattr(proxies, 'has_key'), "proxies must be a mapping" self.proxies = proxies self.key_file = x509.get('key_file') self.cert_file = x509.get('cert_file') + self.context = context self.addheaders = [('User-Agent', self.version)] self.__tempfiles = [] self.__unlink = os.unlink # See cleanup() @@ -422,7 +427,8 @@ class URLopener: auth = None h = httplib.HTTPS(host, 0, key_file=self.key_file, - cert_file=self.cert_file) + cert_file=self.cert_file, + context=self.context) if data is not None: h.putrequest('POST', selector) h.putheader('Content-Type',