From 8bc87c62a118c75a6cbf69c0edfa3ba5acbf3950 Mon Sep 17 00:00:00 2001 From: Eoghan Glynn Date: Tue, 28 Feb 2012 20:22:19 +0000 Subject: 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 --- nova/api/openstack/wsgi.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'nova/api') 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): """ -- cgit