Merge pull request #86 from niphlod/feature/cache.action

cache.action now works with actions raising HTTP internally
This commit is contained in:
mdipierro committed 2013-05-01 06:46:02 -07:00
commit 193510b57d
1 file changed
+40 -8
+40 -8
View File
@@ -461,9 +461,11 @@ class Cache(object):
fast overrides with initial strings, e.g. 'SVLP' or 'VLP', or 'VLP' fast overrides with initial strings, e.g. 'SVLP' or 'VLP', or 'VLP'
""" """
from gluon import current from gluon import current
from gluon.http import HTTP
def wrap(func): def wrap(func):
def wrapped_f(): def wrapped_f():
if current.request.env.request_method == 'GET': if current.request.env.request_method != 'GET':
return func()
if time_expire: if time_expire:
cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire) cache_control = 'max-age=%(time_expire)s, s-maxage=%(time_expire)s' % dict(time_expire=time_expire)
if quick: if quick:
@@ -482,6 +484,7 @@ class Cache(object):
cache_control += ', private' cache_control += ', private'
expires = 'Fri, 01 Jan 1990 00:00:00 GMT' expires = 'Fri, 01 Jan 1990 00:00:00 GMT'
if cache_model: if cache_model:
#figure out the correct cache key
cache_key = [current.request.env.path_info, current.response.view] cache_key = [current.request.env.path_info, current.response.view]
if session_: if session_:
cache_key.append(current.response.session_id) cache_key.append(current.response.session_id)
@@ -497,24 +500,53 @@ class Cache(object):
cache_key = hashlib.md5('__'.join(cache_key)).hexdigest() cache_key = hashlib.md5('__'.join(cache_key)).hexdigest()
if prefix: if prefix:
cache_key = prefix + cache_key cache_key = prefix + cache_key
try:
#action returns something
rtn = cache_model(cache_key, lambda : func(), time_expire=time_expire) rtn = cache_model(cache_key, lambda : func(), time_expire=time_expire)
http, status = None, current.response.status
except HTTP, e:
#action raises HTTP (can still be valid)
rtn = cache_model(cache_key, lambda : e.body, time_expire=time_expire)
http, status = HTTP(e.status, rtn, **e.headers), e.status
else: else:
#action raised a generic exception
http = None
else:
#no server-cache side involved
try:
#action returns something
rtn = func() rtn = func()
http, status = None, current.response.status
except HTTP, e:
#action raises HTTP (can still be valid)
status = e.status
http = HTTP(e.status, e.body, **e.headers)
else:
#action raised a generic exception
http = None
send_headers = False send_headers = False
if isinstance(valid_statuses, list): if http and isinstance(valid_statuses, list):
if current.response.status in valid_statuses: if status in valid_statuses:
send_headers = True send_headers = True
elif valid_statuses is None: elif valid_statuses is None:
if str(current.response.status)[0] in '123': if str(status)[0] in '123':
send_headers = True send_headers = True
if send_headers: if send_headers:
current.response.headers['Pragma'] = None headers = {
current.response.headers['Expires'] = expires 'Pragma' : None,
current.response.headers['Cache-Control'] = cache_control 'Expires' : expires,
'Cache-Control' : cache_control
}
current.response.headers.update(headers)
if cache_model and not send_headers: if cache_model and not send_headers:
#we cached already the value, but the status is not valid
#so we need to delete the cached value
cache_model(cache_key, None) cache_model(cache_key, None)
if http:
if send_headers:
http.headers.update(current.response.headers)
raise http
return rtn return rtn
return func()
wrapped_f.__name__ = func.__name__ wrapped_f.__name__ = func.__name__
wrapped_f.__doc__ = func.__doc__ wrapped_f.__doc__ = func.__doc__
return wrapped_f return wrapped_f