]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Improve error when redirecting with custom schemes (#1002)
authorJosep Cugat <jcugat@gmail.com>
Thu, 28 May 2020 11:11:17 +0000 (13:11 +0200)
committerGitHub <noreply@github.com>
Thu, 28 May 2020 11:11:17 +0000 (13:11 +0200)
Fixes #822

httpx/_client.py
tests/client/test_redirects.py

index 7248f87ce9a8b99cca5a21c35431e686aa5e515d..2c56edc560ebb5ab012edbee540d7f36085fe1fd 100644 (file)
@@ -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:
index e91bb7e66fe81c3d7beb6475e0cc948704249a86..fa5ae4eb536a93574cfed53e2e4988fab1cfa414 100644 (file)
@@ -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.'