diff --git a/CHANGELOG.md b/CHANGELOG.md index e73405c..1873648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/kiota_http/_version.py b/kiota_http/_version.py index a9ecfe2..9035c05 100644 --- a/kiota_http/_version.py +++ b/kiota_http/_version.py @@ -1 +1 @@ -VERSION: str = '1.2.0' +VERSION: str = '1.2.1' diff --git a/kiota_http/middleware/options/redirect_handler_option.py b/kiota_http/middleware/options/redirect_handler_option.py index a2a6c3a..9f0c43a 100644 --- a/kiota_http/middleware/options/redirect_handler_option.py +++ b/kiota_http/middleware/options/redirect_handler_option.py @@ -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 diff --git a/kiota_http/middleware/redirect_handler.py b/kiota_http/middleware/redirect_handler.py index 8677770..5aafcbe 100644 --- a/kiota_http/middleware/redirect_handler.py +++ b/kiota_http/middleware/redirect_handler.py @@ -31,9 +31,8 @@ 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. @@ -41,8 +40,7 @@ def increment(self, response, max_redirect) -> bool: 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]: @@ -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: diff --git a/tests/middleware_tests/test_redirect_handler.py b/tests/middleware_tests/test_redirect_handler.py index b31f103..4006d6c 100644 --- a/tests/middleware_tests/test_redirect_handler.py +++ b/tests/middleware_tests/test_redirect_handler.py @@ -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):