]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Fix for streaming a redirect response body with allow_redirects=False (#766)
authorTom Christie <tom@tomchristie.com>
Fri, 17 Jan 2020 09:45:37 +0000 (09:45 +0000)
committerGitHub <noreply@github.com>
Fri, 17 Jan 2020 09:45:37 +0000 (09:45 +0000)
httpx/client.py
tests/client/test_redirects.py

index 9eec6641bb39887a7238cefc6ac9842d2c675026..590d5d0ed2e517fee636c3fe9f82cbd6a24d05c3 100644 (file)
@@ -622,7 +622,8 @@ class Client(BaseClient):
             if not response.is_redirect:
                 return response
 
-            response.read()
+            if allow_redirects:
+                response.read()
             request = self.build_redirect_request(request, response)
             history = history + [response]
 
@@ -1146,7 +1147,8 @@ class AsyncClient(BaseClient):
             if not response.is_redirect:
                 return response
 
-            await response.aread()
+            if allow_redirects:
+                await response.aread()
             request = self.build_redirect_request(request, response)
             history = history + [response]
 
index a48e478eff96576f844c7fd11c19750a67debbba..eab44f01623c495ba3bf48bc4f40b3c05dad46c2 100644 (file)
@@ -15,6 +15,7 @@ from httpx import (
     codes,
 )
 from httpx.config import CertTypes, TimeoutTypes, VerifyTypes
+from httpx.content_streams import AsyncIteratorStream
 from httpx.dispatch.base import AsyncDispatcher
 
 
@@ -30,9 +31,16 @@ class MockDispatch(AsyncDispatcher):
             return Response(codes.OK, request=request)
 
         elif request.url.path == "/redirect_301":
+
+            async def body():
+                yield b"<a href='https://example.org/'>here</a>"
+
             status_code = codes.MOVED_PERMANENTLY
             headers = {"location": "https://example.org/"}
-            return Response(status_code, headers=headers, request=request)
+            stream = AsyncIteratorStream(aiterator=body())
+            return Response(
+                status_code, stream=stream, headers=headers, request=request
+            )
 
         elif request.url.path == "/redirect_302":
             status_code = codes.FOUND
@@ -285,6 +293,16 @@ async def test_no_body_redirect():
     assert "content-length" not in response.json()["headers"]
 
 
+@pytest.mark.usefixtures("async_environment")
+async def test_can_stream_if_no_redirect():
+    client = AsyncClient(dispatch=MockDispatch())
+    url = "https://example.org/redirect_301"
+    async with client.stream("GET", url, allow_redirects=False) as response:
+        assert not response.is_closed
+    assert response.status_code == codes.MOVED_PERMANENTLY
+    assert response.headers["location"] == "https://example.org/"
+
+
 @pytest.mark.usefixtures("async_environment")
 async def test_cannot_redirect_streaming_body():
     client = AsyncClient(dispatch=MockDispatch())