Skip to content

Commit

Permalink
Per RFC-6585, Tastypie now returns HTTP 429 when the throttle limit i…
Browse files Browse the repository at this point in the history
…s exceeded.
  • Loading branch information
toastdriven committed May 2, 2012
1 parent 3a5cc22 commit c285564
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 6 deletions.
7 changes: 7 additions & 0 deletions docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ Ensures the response is returning a HTTP 409.

Ensures the response is returning a HTTP 410.

``assertHttpTooManyRequests``
~~~~~~~~~~~~~~~~~~~

.. method:: ResourceTestCase.assertHttpTooManyRequests(self, resp)

Ensures the response is returning a HTTP 429.

``assertHttpApplicationError``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
8 changes: 6 additions & 2 deletions tastypie/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

class HttpCreated(HttpResponse):
status_code = 201

def __init__(self, *args, **kwargs):
location = ''

if 'location' in kwargs:
location = kwargs['location']
del(kwargs['location'])

super(HttpCreated, self).__init__(*args, **kwargs)
self['Location'] = location

Expand Down Expand Up @@ -66,6 +66,10 @@ class HttpGone(HttpResponse):
status_code = 410


class HttpTooManyRequests(HttpResponse):
status_code = 429


class HttpApplicationError(HttpResponse):
status_code = 500

Expand Down
2 changes: 1 addition & 1 deletion tastypie/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ def throttle_check(self, request):
# Check to see if they should be throttled.
if self._meta.throttle.should_be_throttled(identifier):
# Throttle limit exceeded.
raise ImmediateHttpResponse(response=http.HttpForbidden())
raise ImmediateHttpResponse(response=http.HttpTooManyRequests())

def log_throttled_access(self, request):
"""
Expand Down
6 changes: 6 additions & 0 deletions tastypie/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,12 @@ def assertHttpGone(self, resp):
"""
return self.assertEqual(resp.status_code, 410)

def assertHttpTooManyRequests(self, resp):
"""
Ensures the response is returning a HTTP 429.
"""
return self.assertEqual(resp.status_code, 429)

def assertHttpApplicationError(self, resp):
"""
Ensures the response is returning a HTTP 500.
Expand Down
2 changes: 2 additions & 0 deletions tests/core/tests/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ def test_various_statuses(self):
self.assertEqual(conflict.status_code, 409)
gone = HttpGone()
self.assertEqual(gone.status_code, 410)
toomanyrequests = HttpTooManyRequests()
self.assertEqual(toomanyrequests.status_code, 429)
not_implemented = HttpNotImplemented()
self.assertEqual(not_implemented.status_code, 501)
6 changes: 3 additions & 3 deletions tests/core/tests/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -2239,20 +2239,20 @@ def test_check_throttling(self):
resp = resource.dispatch('list', request)
self.fail()
except ImmediateHttpResponse, e:
self.assertEqual(e.response.status_code, 403)
self.assertEqual(e.response.status_code, 429)
self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)

# Throttled.
try:
resp = resource.dispatch('list', request)
self.fail()
except ImmediateHttpResponse, e:
self.assertEqual(e.response.status_code, 403)
self.assertEqual(e.response.status_code, 429)
self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)

# Check the ``wrap_view``.
resp = resource.wrap_view('dispatch_list')(request)
self.assertEqual(resp.status_code, 403)
self.assertEqual(resp.status_code, 429)
self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)

# Restore.
Expand Down

0 comments on commit c285564

Please sign in to comment.