diff --git a/httpx/_client.py b/httpx/_client.py index 13cd933673..763f6577e2 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -985,13 +985,18 @@ def _send_handling_redirects( if not response.has_redirect_location: return response - request = self._build_redirect_request(request, response) + try: + next_request = self._build_redirect_request(request, response) + except (InvalidURL, RemoteProtocolError): + return response + history = history + [response] if follow_redirects: response.read() + request = next_request else: - response.next_request = request + response.next_request = next_request return response except BaseException as exc: @@ -1701,13 +1706,18 @@ async def _send_handling_redirects( if not response.has_redirect_location: return response - request = self._build_redirect_request(request, response) + try: + next_request = self._build_redirect_request(request, response) + except (InvalidURL, RemoteProtocolError): + return response + history = history + [response] if follow_redirects: await response.aread() + request = next_request else: - response.next_request = request + response.next_request = next_request return response except BaseException as exc: diff --git a/tests/client/test_redirects.py b/tests/client/test_redirects.py index f65827134c..5150e17114 100644 --- a/tests/client/test_redirects.py +++ b/tests/client/test_redirects.py @@ -202,8 +202,11 @@ def test_malformed_redirect(): def test_invalid_redirect(): client = httpx.Client(transport=httpx.MockTransport(redirects)) - with pytest.raises(httpx.RemoteProtocolError): - client.get("http://example.org/invalid_redirect", follow_redirects=True) + response = client.get("http://example.org/invalid_redirect", follow_redirects=True) + assert response.status_code == httpx.codes.SEE_OTHER + assert response.url == "http://example.org/invalid_redirect" + assert not response.history + assert response.next_request is None def test_no_scheme_redirect(): @@ -441,7 +444,10 @@ def test_redirect_custom_scheme(): @pytest.mark.anyio async def test_async_invalid_redirect(): async with httpx.AsyncClient(transport=httpx.MockTransport(redirects)) as client: - with pytest.raises(httpx.RemoteProtocolError): - await client.get( - "http://example.org/invalid_redirect", follow_redirects=True - ) + response = await client.get( + "http://example.org/invalid_redirect", follow_redirects=True + ) + assert response.status_code == httpx.codes.SEE_OTHER + assert response.url == "http://example.org/invalid_redirect" + assert not response.history + assert response.next_request is None