Handle 'None' return value of wait() properly during throttling. (#6837)

This commit is contained in:
Christopher Grebs 2019-08-12 20:36:05 +02:00 committed by Ryan P Kilby
parent a142467586
commit 5a8736ae45
2 changed files with 30 additions and 1 deletions

View File

@ -356,7 +356,15 @@ class APIView(View):
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):
"""

View File

@ -159,6 +159,27 @@ class ThrottlingTests(TestCase):
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