From: Josep Cugat Date: Thu, 28 May 2020 11:11:17 +0000 (+0200) Subject: Improve error when redirecting with custom schemes (#1002) X-Git-Tag: 0.13.3~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=093cb4250006dc0b73af986f7e6537b8c4395dcf;p=thirdparty%2Fhttpx.git Improve error when redirecting with custom schemes (#1002) Fixes #822 --- diff --git a/httpx/_client.py b/httpx/_client.py index 7248f87c..2c56edc5 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -322,6 +322,10 @@ class BaseClient: url = URL(location, allow_relative=True) + # Check that we can handle the scheme + if url.scheme and url.scheme not in ("http", "https"): + raise InvalidURL(f'Scheme "{url.scheme}" not supported.') + # Handle malformed 'Location' headers that are "absolute" form, have no host. # See: https://github.com/encode/httpx/issues/771 if url.scheme and not url.host: diff --git a/tests/client/test_redirects.py b/tests/client/test_redirects.py index e91bb7e6..fa5ae4eb 100644 --- a/tests/client/test_redirects.py +++ b/tests/client/test_redirects.py @@ -8,6 +8,7 @@ import pytest from httpx import ( URL, AsyncClient, + InvalidURL, NotRedirectResponse, RequestBodyUnavailable, TooManyRedirects, @@ -140,6 +141,17 @@ class MockDispatch(httpcore.AsyncHTTPTransport): else: return b"HTTP/1.1", 200, b"OK", [], ByteStream(b"Hello, world!") + elif path == b"/redirect_custom_scheme": + status_code = codes.MOVED_PERMANENTLY + headers = [(b"location", b"market://details?id=42")] + return ( + b"HTTP/1.1", + status_code, + b"Moved Permanently", + headers, + ByteStream(b""), + ) + return b"HTTP/1.1", 200, b"OK", [], ByteStream(b"Hello, world!") @@ -431,3 +443,11 @@ async def test_redirect_cookie_behavior(): response = await client.get("https://example.com/") assert response.url == "https://example.com/" assert response.text == "Not logged in" + + +@pytest.mark.usefixtures("async_environment") +async def test_redirect_custom_scheme(): + client = AsyncClient(dispatch=MockDispatch()) + with pytest.raises(InvalidURL) as e: + await client.post("https://example.org/redirect_custom_scheme") + assert str(e.value) == 'Scheme "market" not supported.'