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

Neaten up our try...except structure for ensuring responses #1525

Merged
merged 1 commit into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 62 additions & 54 deletions httpx/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,21 +762,18 @@ def send(
allow_redirects=allow_redirects,
history=[],
)

if not stream:
try:
try:
if not stream:
response.read()
finally:
response.close()

try:
for hook in self._event_hooks["response"]:
hook(response)
except Exception:
response.close()
raise

return response
return response

except Exception as exc:
response.close()
raise exc

def _send_handling_auth(
self,
Expand All @@ -800,18 +797,20 @@ def _send_handling_auth(
history=history,
)
try:
next_request = auth_flow.send(response)
except StopIteration:
return response
except BaseException as exc:
response.close()
raise exc from None
else:
try:
next_request = auth_flow.send(response)
except StopIteration:
return response

response.history = list(history)
response.read()
request = next_request
history.append(response)

except Exception as exc:
response.close()
raise exc

def _send_handling_redirects(
self,
request: Request,
Expand All @@ -826,19 +825,24 @@ def _send_handling_redirects(
)

response = self._send_single_request(request, timeout)
response.history = list(history)
try:
response.history = list(history)

if not response.is_redirect:
return response
if not response.is_redirect:
return response

if allow_redirects:
response.read()
request = self._build_redirect_request(request, response)
history = history + [response]
request = self._build_redirect_request(request, response)
history = history + [response]

if not allow_redirects:
response.next_request = request
return response
if allow_redirects:
response.read()
else:
response.next_request = request
return response

except Exception as exc:
response.close()
raise exc

def _send_single_request(self, request: Request, timeout: Timeout) -> Response:
"""
Expand Down Expand Up @@ -1394,21 +1398,18 @@ async def send(
allow_redirects=allow_redirects,
history=[],
)

if not stream:
try:
try:
if not stream:
await response.aread()
finally:
await response.aclose()

try:
for hook in self._event_hooks["response"]:
await hook(response)
except Exception:
await response.aclose()
raise

return response
return response

except Exception as exc:
await response.aclose()
raise exc

async def _send_handling_auth(
self,
Expand All @@ -1432,18 +1433,20 @@ async def _send_handling_auth(
history=history,
)
try:
next_request = await auth_flow.asend(response)
except StopAsyncIteration:
return response
except BaseException as exc:
await response.aclose()
raise exc from None
else:
try:
next_request = await auth_flow.asend(response)
except StopAsyncIteration:
return response

response.history = list(history)
await response.aread()
request = next_request
history.append(response)

except Exception as exc:
await response.aclose()
raise exc

async def _send_handling_redirects(
self,
request: Request,
Expand All @@ -1458,19 +1461,24 @@ async def _send_handling_redirects(
)

response = await self._send_single_request(request, timeout)
response.history = list(history)
try:
response.history = list(history)

if not response.is_redirect:
return response
if not response.is_redirect:
return response

if allow_redirects:
await response.aread()
request = self._build_redirect_request(request, response)
history = history + [response]
request = self._build_redirect_request(request, response)
history = history + [response]

if not allow_redirects:
response.next_request = request
return response
if allow_redirects:
await response.aread()
else:
response.next_request = request
return response

except Exception as exc:
await response.aclose()
raise exc

async def _send_single_request(
self, request: Request, timeout: Timeout
Expand Down
7 changes: 7 additions & 0 deletions tests/client/test_redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,10 @@ def test_redirect_custom_scheme():
with pytest.raises(httpx.UnsupportedProtocol) as e:
client.post("https://example.org/redirect_custom_scheme")
assert str(e.value) == "Scheme 'market' not supported."


@pytest.mark.usefixtures("async_environment")
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")