Wrap urllib3's SSLError as requests' SSLError (#6057)

This commit is contained in:
Nate Prewitt
2022-02-05 11:56:05 -07:00
committed by GitHub
parent 7ae38876b1
commit 95f4567336
3 changed files with 55 additions and 5 deletions
+5
View File
@@ -6,6 +6,11 @@ dev
- \[Short description of non-trivial change.\]
**Bugfixes**
- Fixed urllib3 exception leak, wrapping `urllib3.exceptions.SSLError` with
`requests.exceptions.SSLError` for `content` and `iter_content`.
2.27.1 (2022-01-05)
-------------------
+9 -1
View File
@@ -19,7 +19,12 @@ from urllib3.fields import RequestField
from urllib3.filepost import encode_multipart_formdata
from urllib3.util import parse_url
from urllib3.exceptions import (
DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
DecodeError,
LocationParseError,
ProtocolError,
ReadTimeoutError,
SSLError,
)
from io import UnsupportedOperation
from .hooks import default_hooks
@@ -32,6 +37,7 @@ from .exceptions import (
ContentDecodingError, ConnectionError, StreamConsumedError,
InvalidJSONError)
from .exceptions import JSONDecodeError as RequestsJSONDecodeError
from .exceptions import SSLError as RequestsSSLError
from ._internal_utils import to_native_string, unicode_is_ascii
from .utils import (
guess_filename, get_auth_from_url, requote_uri,
@@ -765,6 +771,8 @@ class Response(object):
raise ContentDecodingError(e)
except ReadTimeoutError as e:
raise ConnectionError(e)
except SSLError as e:
raise RequestsSSLError(e)
else:
# Standard file-like object.
while True:
+41 -4
View File
@@ -14,6 +14,7 @@ import re
import io
import requests
import pytest
import urllib3
from requests.adapters import HTTPAdapter
from requests.auth import HTTPDigestAuth, _basic_auth_str
from requests.compat import (
@@ -22,9 +23,25 @@ from requests.compat import (
from requests.cookies import (
cookiejar_from_dict, morsel_to_cookie)
from requests.exceptions import (
ConnectionError, ConnectTimeout, InvalidSchema, InvalidURL,
MissingSchema, ReadTimeout, Timeout, RetryError, RequestException, TooManyRedirects,
ProxyError, InvalidHeader, UnrewindableBodyError, SSLError, InvalidProxyURL, InvalidJSONError)
ChunkedEncodingError,
ConnectionError,
ConnectTimeout,
ContentDecodingError,
InvalidHeader,
InvalidJSONError,
InvalidProxyURL,
InvalidSchema,
InvalidURL,
MissingSchema,
ProxyError,
ReadTimeout,
RequestException,
RetryError,
Timeout,
TooManyRedirects,
UnrewindableBodyError,
)
from requests.exceptions import SSLError as RequestsSSLError
from requests.models import PreparedRequest
from requests.structures import CaseInsensitiveDict
from requests.sessions import SessionRedirectMixin
@@ -910,7 +927,7 @@ class TestRequests:
"""
When underlying SSL problems occur, an SSLError is raised.
"""
with pytest.raises(SSLError):
with pytest.raises(RequestsSSLError):
# 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'))
@@ -1320,6 +1337,26 @@ class TestRequests:
with pytest.raises(TypeError):
chunks = r.iter_content("1024")
@pytest.mark.parametrize(
'exception, args, expected', (
(urllib3.exceptions.ProtocolError, tuple(), ChunkedEncodingError),
(urllib3.exceptions.DecodeError, tuple(), ContentDecodingError),
(urllib3.exceptions.ReadTimeoutError, (None, '', ''), ConnectionError),
(urllib3.exceptions.SSLError, tuple(), RequestsSSLError),
)
)
def test_iter_content_wraps_exceptions(
self, httpbin, mocker, exception, args, expected
):
r = requests.Response()
r.raw = mocker.Mock()
# ReadTimeoutError can't be initialized by mock
# so we'll manually create the instance with args
r.raw.stream.side_effect = exception(*args)
with pytest.raises(expected):
next(r.iter_content(1024))
def test_request_and_response_are_pickleable(self, httpbin):
r = requests.get(httpbin('get'))