diff options
| author | Tom Christie | 2011-06-15 14:41:09 +0100 |
|---|---|---|
| committer | Tom Christie | 2011-06-15 14:41:09 +0100 |
| commit | 1cb84cd4e82880caea645ebd99a947cead3096b9 (patch) | |
| tree | 5ae955f4a7ef5cd9754f2b5c11caecdedcad1f10 /djangorestframework/permissions.py | |
| parent | ff6e78323f88fd58b1de5b02e2440c2fc24c9c8b (diff) | |
| parent | 49a2817eb5ccf5f176ff5366d69df3a307dfcda2 (diff) | |
| download | django-rest-framework-1cb84cd4e82880caea645ebd99a947cead3096b9.tar.bz2 | |
Merge throttling and fix up a coupla things
Diffstat (limited to 'djangorestframework/permissions.py')
| -rw-r--r-- | djangorestframework/permissions.py | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/djangorestframework/permissions.py b/djangorestframework/permissions.py index 34ab5bf4..7dcabcf0 100644 --- a/djangorestframework/permissions.py +++ b/djangorestframework/permissions.py @@ -31,11 +31,6 @@ _503_SERVICE_UNAVAILABLE = ErrorResponse( {'detail': 'request was throttled'}) -class ConfigurationException(BaseException): - """To alert for bad configuration decisions as a convenience.""" - pass - - class BasePermission(object): """ A base class from which all permission classes should inherit. @@ -142,14 +137,13 @@ class BaseThrottle(BasePermission): # Drop any requests from the history which have now passed the # throttle duration - while self.history and self.history[0] <= self.now - self.duration: + while self.history and self.history[-1] <= self.now - self.duration: self.history.pop() - if len(self.history) >= self.num_requests: self.throttle_failure() else: self.throttle_success() - + def throttle_success(self): """ Inserts the current request's timestamp along with the key @@ -157,13 +151,30 @@ class BaseThrottle(BasePermission): """ self.history.insert(0, self.now) cache.set(self.key, self.history, self.duration) - + header = 'status=SUCCESS; next=%s sec' % self.next() + self.view.add_header('X-Throttle', header) + def throttle_failure(self): """ Called when a request to the API has failed due to throttling. Raises a '503 service unavailable' response. """ + header = 'status=FAILURE; next=%s sec' % self.next() + self.view.add_header('X-Throttle', header) raise _503_SERVICE_UNAVAILABLE + + def next(self): + """ + Returns the recommended next request time in seconds. + """ + if self.history: + remaining_duration = self.duration - (self.now - self.history[-1]) + else: + remaining_duration = self.duration + + available_requests = self.num_requests - len(self.history) + 1 + + return '%.2f' % (remaining_duration / float(available_requests)) class PerUserThrottling(BaseThrottle): |
