Skip to content

Commit

Permalink
Appropriately handle urllib3's InvalidHeader exception
Browse files Browse the repository at this point in the history
  • Loading branch information
nateprewitt committed Aug 27, 2021
1 parent b351e90 commit 769ac18
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
5 changes: 4 additions & 1 deletion requests/adapters.py
Expand Up @@ -19,6 +19,7 @@
from urllib3.exceptions import ClosedPoolError
from urllib3.exceptions import ConnectTimeoutError
from urllib3.exceptions import HTTPError as _HTTPError
from urllib3.exceptions import InvalidHeader as _InvalidHeader
from urllib3.exceptions import MaxRetryError
from urllib3.exceptions import NewConnectionError
from urllib3.exceptions import ProxyError as _ProxyError
Expand All @@ -37,7 +38,7 @@
from .cookies import extract_cookies_to_jar
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
ProxyError, RetryError, InvalidSchema, InvalidProxyURL,
InvalidURL)
InvalidURL, InvalidHeader)
from .auth import _basic_auth_str

try:
Expand Down Expand Up @@ -527,6 +528,8 @@ def send(self, request, stream=False, timeout=None, verify=True, cert=None, prox
raise SSLError(e, request=request)
elif isinstance(e, ReadTimeoutError):
raise ReadTimeout(e, request=request)
elif isinstance(e, _InvalidHeader):
raise InvalidHeader(e, request=request)
else:
raise

Expand Down
26 changes: 26 additions & 0 deletions tests/test_lowlevel.py
Expand Up @@ -46,6 +46,32 @@ def incomplete_chunked_response_handler(sock):
close_server.set() # release server block


def test_conflicting_content_lengths():
"""Ensure we correctly throw an InvalidHeader error if multiple
conflicting Content-Length headers are returned.
"""

def multiple_content_length_response_handler(sock):
request_content = consume_socket_content(sock, timeout=0.5)

sock.send(b"HTTP/1.1 200 OK\r\n" +
b"Content-Type: text/plain\r\n" +
b"Content-Length: 16\r\n" +
b"Content-Length: 32\r\n\r\n" +
b"-- Bad Actor -- Original Content\r\n")

return request_content

close_server = threading.Event()
server = Server(multiple_content_length_response_handler)

with server as (host, port):
url = 'http://{}:{}/'.format(host, port)
with pytest.raises(requests.exceptions.InvalidHeader):
r = requests.get(url)
close_server.set()


def test_digestauth_401_count_reset_on_redirect():
"""Ensure we correctly reset num_401_calls after a successful digest auth,
followed by a 302 redirect to another digest auth prompt.
Expand Down

0 comments on commit 769ac18

Please sign in to comment.