Skip to content
This repository was archived by the owner on Oct 14, 2024. It is now read-only.

Shem/max redirect state update #258

Merged
merged 9 commits into from
Jan 22, 2024
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.1] - 2024-01-22

### Added

### Changed

- Fixed bug with redirect handler maintaing `max_redirect` across requests.[#246](https://github.com/microsoft/kiota-http-python/issues/246)

## [1.2.0] - 2023-11-29

### Added
Expand Down
2 changes: 1 addition & 1 deletion kiota_http/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION: str = '1.2.0'
VERSION: str = '1.2.1'
1 change: 0 additions & 1 deletion kiota_http/middleware/options/redirect_handler_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def __init__(
raise ValueError(
"MaxLimitExceeded. Negative value for max_redirect property is invalid"
)

self._max_redirect = max_redirect
self._should_redirect = should_redirect
self._allow_redirect_on_scheme_change = allow_redirect_on_scheme_change
Expand Down
33 changes: 19 additions & 14 deletions kiota_http/middleware/redirect_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,16 @@ def __init__(self, options: RequestOption = RedirectHandlerOption()) -> None:
super().__init__()
self.options = options
self.redirect_on_status_codes: typing.Set[int] = self.DEFAULT_REDIRECT_STATUS_CODES
self.history: typing.List[httpx.Request] = []

def increment(self, response, max_redirect) -> bool:
def increment(self, response, max_redirect, history) -> bool:
"""Increment the redirect attempts for this request.
Args
response(httpx.Response): A httpx response object.
Returns:
bool: Whether further redirect attempts are remaining.
False if exhausted; True if more redirect attempts available.
"""

self.history.append(response.request)
history.append(response.request)
return max_redirect >= 0

def get_redirect_location(self, response: httpx.Response) -> typing.Union[str, bool, None]:
Expand All @@ -69,28 +67,35 @@ async def send(
_enable_span.set_attribute(REDIRECT_ENABLE_KEY, True)
_enable_span.end()

retryable = True
_redirect_span = self._create_observability_span(
request, f"RedirectHandler_send - redirect {len(self.history)}"
)
while retryable:
max_redirect = current_options.max_redirect
history: typing.List[httpx.Request] = []

while max_redirect >= 0:
_redirect_span = self._create_observability_span(
request, f"RedirectHandler_send - redirect {len(history)}"
)
response = await super().send(request, transport)
_redirect_span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, response.status_code)
redirect_location = self.get_redirect_location(response)

if redirect_location and current_options.should_redirect:
current_options.max_redirect -= 1
retryable = self.increment(response, current_options.max_redirect)
_redirect_span.set_attribute(REDIRECT_COUNT_KEY, len(self.history))
max_redirect -= 1
if not self.increment(response, max_redirect, history[:]):
break
_redirect_span.set_attribute(REDIRECT_COUNT_KEY, len(history))
new_request = self._build_redirect_request(request, response)
request = new_request
continue
response.history = self.history

response.history = history
break
if not retryable:

if max_redirect < 0:
exc = RedirectError(f"Too many redirects. {response.history}")
_redirect_span.record_exception(exc)
_redirect_span.end()
raise exc

return response

def _get_current_options(self, request: httpx.Request) -> RedirectHandlerOption:
Expand Down
3 changes: 2 additions & 1 deletion tests/middleware_tests/test_redirect_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ def test_increment_redirects():
"""
request = httpx.Request('GET', BASE_URL)
response = httpx.Response(301, request=request)
history = []

handler = RedirectHandler()
assert handler.increment(response, handler.options.max_redirect)
assert handler.increment(response, handler.options.max_redirect, history=history)


def test_same_origin(mock_redirect_handler):
Expand Down