diff --git a/AUTHORS.rst b/AUTHORS.rst index c5218c6a..b87dc443 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -10,13 +10,6 @@ Keepers of the Four Crystals - Nate Prewitt `@nateprewitt `_ - -Urllib3 -``````` - -- Andrey Petrov - - Patches and Suggestions ``````````````````````` diff --git a/HISTORY.rst b/HISTORY.rst index 4c6bc740..de6ba5c4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -10,6 +10,22 @@ dev **Bugfixes** +**Dependencies** + +- We now support idna v2.6. + +2.18.3 (2017-08-02) ++++++++++++++++++++ + +**Improvements** + +- Running ``$ python -m requests.help`` now includes the installed version of idna. + +**Bugfixes** + +- Fixed issue where Requests would raise ``ConnectionError`` instead of + ``SSLError`` when encountering SSL problems when using urllib3 v1.22. + 2.18.2 (2017-07-25) +++++++++++++++++++ diff --git a/docs/user/advanced.rst b/docs/user/advanced.rst index a1b68707..4aa1dfac 100644 --- a/docs/user/advanced.rst +++ b/docs/user/advanced.rst @@ -593,6 +593,8 @@ as using a HTTP one:: 'https': 'socks5://user:pass@host:port' } +Using the scheme ``socks5`` causes the DNS resolution to happen on the client, rather than on the proxy server. This is in line with curl, which uses the scheme to decide whether to do the DNS resolution on the client or proxy. If you want to resolve the domains on the proxy server, use ``socks5h`` as the scheme. + .. _compliance: Compliance diff --git a/requests/__version__.py b/requests/__version__.py index 156ff20a..2d60bcc0 100644 --- a/requests/__version__.py +++ b/requests/__version__.py @@ -5,8 +5,8 @@ __title__ = 'requests' __description__ = 'Python HTTP for Humans.' __url__ = 'http://python-requests.org' -__version__ = '2.18.2' -__build__ = 0x021802 +__version__ = '2.18.3' +__build__ = 0x021803 __author__ = 'Kenneth Reitz' __author_email__ = 'me@kennethreitz.org' __license__ = 'Apache 2.0' diff --git a/requests/adapters.py b/requests/adapters.py index 205da0cd..00f8792b 100644 --- a/requests/adapters.py +++ b/requests/adapters.py @@ -501,6 +501,10 @@ class HTTPAdapter(BaseAdapter): if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + raise ConnectionError(e, request=request) except ClosedPoolError as e: @@ -511,6 +515,7 @@ class HTTPAdapter(BaseAdapter): except (_SSLError, _HTTPError) as e: if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 raise SSLError(e, request=request) elif isinstance(e, ReadTimeoutError): raise ReadTimeout(e, request=request) diff --git a/requests/compat.py b/requests/compat.py index 5c09ea88..f417cfd8 100644 --- a/requests/compat.py +++ b/requests/compat.py @@ -27,9 +27,7 @@ is_py3 = (_ver[0] == 3) try: import simplejson as json -except (ImportError, SyntaxError): - # simplejson does not support Python 3.2, it throws a SyntaxError - # because of u'...' Unicode literals. +except ImportError: import json # --------- diff --git a/requests/help.py b/requests/help.py index cd961c78..5440ee61 100644 --- a/requests/help.py +++ b/requests/help.py @@ -6,6 +6,7 @@ import platform import sys import ssl +import idna import urllib3 import chardet @@ -84,6 +85,9 @@ def info(): cryptography_info = { 'version': getattr(cryptography, '__version__', ''), } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) @@ -100,6 +104,7 @@ def info(): 'urllib3': urllib3_info, 'chardet': chardet_info, 'cryptography': cryptography_info, + 'idna': idna_info, 'requests': { 'version': requests_version, }, diff --git a/requests/models.py b/requests/models.py index 2148024f..4041cac3 100644 --- a/requests/models.py +++ b/requests/models.py @@ -586,8 +586,6 @@ class Response(object): ] def __init__(self): - super(Response, self).__init__() - self._content = False self._content_consumed = False self._next = None diff --git a/setup.py b/setup.py index 98702858..25887bb3 100755 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ packages = ['requests'] requires = [ 'chardet>=3.0.2,<3.1.0', - 'idna>=2.5,<2.6', + 'idna>=2.5,<2.7', 'urllib3>=1.21.1,<1.23', 'certifi>=2017.4.17' diff --git a/tests/test_help.py b/tests/test_help.py index f08fdd97..c11d43f3 100644 --- a/tests/test_help.py +++ b/tests/test_help.py @@ -19,3 +19,22 @@ def test_system_ssl_py26(): def test_system_ssl(): """Verify we're actually setting system_ssl when it should be available.""" assert info()['system_ssl']['version'] != '' + + +class VersionedPackage(object): + def __init__(self, version): + self.__version__ = version + + +def test_idna_without_version_attribute(mocker): + """Older versions of IDNA don't provide a __version__ attribute, verify + that if we have such a package, we don't blow up. + """ + mocker.patch('requests.help.idna', new=None) + assert info()['idna'] == {'version': ''} + + +def test_idna_with_version_attribute(mocker): + """Verify we're actually setting idna version when it should be available.""" + mocker.patch('requests.help.idna', new=VersionedPackage('2.6')) + assert info()['idna'] == {'version': '2.6'} diff --git a/tests/test_requests.py b/tests/test_requests.py index cfafc6e4..7ef6bfee 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -23,7 +23,7 @@ from requests.cookies import ( from requests.exceptions import ( ConnectionError, ConnectTimeout, InvalidSchema, InvalidURL, MissingSchema, ReadTimeout, Timeout, RetryError, TooManyRedirects, - ProxyError, InvalidHeader, UnrewindableBodyError) + ProxyError, InvalidHeader, UnrewindableBodyError, SSLError) from requests.models import PreparedRequest from requests.structures import CaseInsensitiveDict from requests.sessions import SessionRedirectMixin @@ -812,6 +812,15 @@ class TestRequests: item.category.__name__ for item in warning_records) assert warnings_category == warnings_expected + def test_certificate_failure(self, httpbin_secure): + """ + When underlying SSL problems occur, an SSLError is raised. + """ + with pytest.raises(SSLError): + # Our local httpbin does not have a trusted CA, so this call will + # fail if we use our default trust bundle. + requests.get(httpbin_secure('status', '200')) + def test_urlencoded_get_query_multivalued_param(self, httpbin): r = requests.get(httpbin('get'), params=dict(test=['foo', 'baz']))