Skip to content

Commit

Permalink
Handle 'None' return value of wait() properly during throttling. (enc…
Browse files Browse the repository at this point in the history
  • Loading branch information
EnTeQuAk authored and sigvef committed Dec 3, 2022
1 parent a2edff0 commit 6226849
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
10 changes: 9 additions & 1 deletion rest_framework/views.py
Expand Up @@ -356,7 +356,15 @@ def check_throttles(self, request):
throttle_durations.append(throttle.wait())

if throttle_durations:
self.throttled(request, max(throttle_durations))
# Filter out `None` values which may happen in case of config / rate
# changes, see #1438
durations = [
duration for duration in throttle_durations
if duration is not None
]

duration = max(durations, default=None)
self.throttled(request, duration)

def determine_version(self, request, *args, **kwargs):
"""
Expand Down
21 changes: 21 additions & 0 deletions tests/test_throttling.py
Expand Up @@ -159,6 +159,27 @@ def test_request_throttling_multiple_throttles(self):
assert response.status_code == 429
assert int(response['retry-after']) == 58

def test_throttle_rate_change_negative(self):
self.set_throttle_timer(MockView_DoubleThrottling, 0)
request = self.factory.get('/')
for dummy in range(24):
response = MockView_DoubleThrottling.as_view()(request)
assert response.status_code == 429
assert int(response['retry-after']) == 60

previous_rate = User3SecRateThrottle.rate
try:
User3SecRateThrottle.rate = '1/sec'

for dummy in range(24):
response = MockView_DoubleThrottling.as_view()(request)

assert response.status_code == 429
assert int(response['retry-after']) == 60
finally:
# reset
User3SecRateThrottle.rate = previous_rate

def ensure_response_header_contains_proper_throttle_field(self, view, expected_headers):
"""
Ensure the response returns an Retry-After field with status and next attributes
Expand Down

0 comments on commit 6226849

Please sign in to comment.