summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEoghan Glynn <eglynn@redhat.com>2012-02-28 20:22:19 +0000
committerEoghan Glynn <eglynn@redhat.com>2012-02-28 20:26:29 +0000
commit8bc87c62a118c75a6cbf69c0edfa3ba5acbf3950 (patch)
tree18404b1d64c56797e82e731e95de1c763e703140
parent85f844c26e1a51665891ede3e5696d13433a7c59 (diff)
downloadnova-8bc87c62a118c75a6cbf69c0edfa3ba5acbf3950.tar.gz
nova-8bc87c62a118c75a6cbf69c0edfa3ba5acbf3950.tar.xz
nova-8bc87c62a118c75a6cbf69c0edfa3ba5acbf3950.zip
Provide retry-after guidance on throttled requests
Fixes bug 942874 Guide the caller's redrive strategy with a Retry-After hint in the 413 response emitted when rate limits are exceeded. The simplest format of Retry-After is used, i.e. number of seconds as opposed to a HTTP time string. Change-Id: I8b1a28f964a111008b1a88d9c0f96c5a0abd8314
-rw-r--r--nova/api/openstack/wsgi.py12
-rw-r--r--nova/tests/api/openstack/compute/test_limits.py4
2 files changed, 15 insertions, 1 deletions
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 8f0259024..047b68956 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -18,6 +18,8 @@
import inspect
from xml.dom import minidom
from xml.parsers import expat
+import math
+import time
from lxml import etree
import webob
@@ -1075,7 +1077,8 @@ class OverLimitFault(webob.exc.HTTPException):
"""
Initialize new `OverLimitFault` with relevant information.
"""
- self.wrapped_exc = webob.exc.HTTPRequestEntityTooLarge()
+ hdrs = OverLimitFault._retry_after(retry_time)
+ self.wrapped_exc = webob.exc.HTTPRequestEntityTooLarge(headers=hdrs)
self.content = {
"overLimitFault": {
"code": self.wrapped_exc.status_int,
@@ -1084,6 +1087,13 @@ class OverLimitFault(webob.exc.HTTPException):
},
}
+ @staticmethod
+ def _retry_after(retry_time):
+ delay = int(math.ceil(retry_time - time.time()))
+ retry_after = delay if delay > 0 else 0
+ headers = {'Retry-After': '%d' % retry_after}
+ return headers
+
@webob.dec.wsgify(RequestClass=Request)
def __call__(self, request):
"""
diff --git a/nova/tests/api/openstack/compute/test_limits.py b/nova/tests/api/openstack/compute/test_limits.py
index 26e0094c0..eb4ab00c4 100644
--- a/nova/tests/api/openstack/compute/test_limits.py
+++ b/nova/tests/api/openstack/compute/test_limits.py
@@ -315,6 +315,10 @@ class LimitMiddlewareTest(BaseLimitTestSuite):
response = request.get_response(self.app)
self.assertEqual(response.status_int, 413)
+ self.assertTrue('Retry-After' in response.headers)
+ retry_after = int(response.headers['Retry-After'])
+ self.assertAlmostEqual(retry_after, 60, 1)
+
body = json.loads(response.body)
expected = "Only 1 GET request(s) can be made to * every minute."
value = body["overLimitFault"]["details"].strip()