Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ maintain transport response history #3155

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions httpx/_client.py
Expand Up @@ -993,13 +993,14 @@ def _send_handling_redirects(
try:
for hook in self._event_hooks["response"]:
hook(response)
response.history = list(history)
transport_history = response.history
response.history = list(history) + transport_history

if not response.has_redirect_location:
return response

request = self._build_redirect_request(request, response)
history = history + [response]
history = history + transport_history + [response]

if follow_redirects:
response.read()
Expand Down Expand Up @@ -1741,14 +1742,14 @@ async def _send_handling_redirects(
try:
for hook in self._event_hooks["response"]:
await hook(response)

response.history = list(history)
transport_history = response.history
response.history = list(history) + transport_history

if not response.has_redirect_location:
return response

request = self._build_redirect_request(request, response)
history = history + [response]
history = history + transport_history + [response]

if follow_redirects:
await response.aread()
Expand Down
28 changes: 28 additions & 0 deletions tests/client/test_redirects.py
Expand Up @@ -107,6 +107,12 @@ def redirects(request: httpx.Request) -> httpx.Response:
headers = {"location": "market://details?id=42"}
return httpx.Response(status_code, headers=headers)

elif request.url.path == "/redirect_303_with_history":
status_code = httpx.codes.SEE_OTHER
headers = {"location": "https://example.org/"}
history = [httpx.Response(status_code, headers=headers)]
return httpx.Response(status_code, headers=headers, history=history)

if request.method == "HEAD":
return httpx.Response(200)

Expand Down Expand Up @@ -445,3 +451,25 @@ async def test_async_invalid_redirect():
await client.get(
"http://example.org/invalid_redirect", follow_redirects=True
)


def test_redirect_303_history():
client = httpx.Client(transport=httpx.MockTransport(redirects))
response = client.get(
"https://example.org/redirect_303_with_history", follow_redirects=True
)
assert response.status_code == httpx.codes.OK
assert response.url == "https://example.org/"
assert len(response.history) == 2


@pytest.mark.anyio
async def test_async_redirect_history():
async with httpx.AsyncClient(transport=httpx.MockTransport(redirects)) as client:
request = client.build_request(
"POST", "https://example.org/redirect_303_with_history"
)
response = await client.send(request, follow_redirects=True)
assert response.status_code == httpx.codes.OK
assert response.url == "https://example.org/"
assert len(response.history) == 2