Twisted 设置缓存头

0 投票
2 回答
1177 浏览
提问于 2025-04-17 21:56

如何在一个GET请求中设置合适的缓存头呢?我想设置expirescache-control,就像下面这样:

我的render_GET看起来差不多是这样的:

def render_GET(self, request):
    data = self.getData(request) #dict
    cache(request)
    request.write(json.dumps(data))
    request.finish()

我写了一个缓存助手,帮助处理这个问题:

from wsgiref.handlers import format_date_time as format_date
from datetime import date, timedelta
from time import mktime

'''
   Sets the cache headers for a (static resource) request
'''
def cache(request, expires=30, public=True):
    #set expires header
    expiry = (date.today() + timedelta(expires)).timetuple()
    request.setHeader("expires" , format_date(mktime(expiry)))

    cache_control = "max-age=" + str(60*60*24*expires)
    if public:
        cache_control += ", public"
    else:
        cache_control += ", private"
    request.setHeader("cache-control", cache_control)

    return request

但是最终得到的响应头并不是我预期的那样:

HTTP/1.1 200 OK
Content-Type: text/html
Date: Wed, 12 Mar 2014 13:03:04 GMT
Server: TwistedWeb/13.1.0
transfer-encoding: chunked

这是实际想要的用法

2 个回答

-1

根据这个关于TwistedMatrix的错误报告,我把request.setHeader()换成了request.responseHeaders.setRawHeaders(),如下所示:

def cache(request, expires=30, public=True):
    #set expires header
    expiry = (date.today() + timedelta(expires)).timetuple()
    request.responseHeaders.setRawHeaders("expires" , [format_date(mktime(expiry))])

    #set cache control
    cache_control = "max-age=" + str(int(60*60*24*expires))
    if public:
        cache_control += ", public"
    else:
        cache_control += ", private"
    request.responseHeaders.setRawHeaders("cache-control", [cache_control])

    return request

这样做的结果是返回的头信息如下:

Accept-Ranges: bytes
Cache-Control: max-age=2592000, public
Connection: keep-alive
Content-Encoding: gzip
Content-length: 0
Date: Wed, 12 Mar 2014 16:18:57 GMT
Expires: Fri, 11 Apr 2014 00:00:00 GMT
Last-Modified: Wed, 12 Mar 2014 15:06:01 GMT
Server: TwistedWeb/13.1.0
2

看你的代码和问题,你的代码中在写入之后有一个cache

 request.write(qjson.dumps(lang))
 cache(request)
 request.finish()

而你提问的地方是在写入之前有cache

def render_GET(self, request):
    data = self.getData(request) #dict
    cache(request)
    request.write(json.dumps(data))
    request.finish()

很可能,你提问里的代码是可以工作的,但你的代码就不一定了。不过正如评论中提到的,这并不是问题的关键。

你没有设置Content-Length这个头信息。如果不设置Content-Length,就会使用分块编码,这样会禁用缓存头信息。

下面的代码可以生成正确的响应头信息:

def render_GET(self, request):
    data = json.dumps(self.getData(request)) #dict
    request.setHeader('Content-Length', len(data))
    cache(request)
    request.write(data)
    request.finish()

灵感来自于以下帖子 http://msoulier.wordpress.com/2010/06/11/twisted-python-and-chunked-encoding/

撰写回答