开了 HTTPCACHE_ENABLED 之后,到底缓存了什么、什么时候失效、磁盘上长什么样?默认的 DummyPolicy 与 RFC2616Policy 差别在哪?这篇把两种策略对 no-store、max-age、ETag、404 等逐个实测,还看了缓存兜底下载失败。
第 1 次运行:服务器收到 3 个请求;cache stats {'firsthand': 3, 'miss': 3, 'store': 3};响应 flags [()]
第 2 次运行:服务器收到 0 个请求;cache stats {'hit': 3};响应 flags [('cached',)]
HTTPCACHE_ENABLED=0(同一个目录):服务器收到 1 个请求;cache stats {}开启后第一次是 miss,响应被存下;再次请求(同一个指纹)命中,不去服务器,响应的 flags 里有 cached。
s/ce/ce204639…/meta 143 字节 s/ce/ce204639…/pickled_meta 113 字节 s/ce/ce204639…/request_body 0 字节 s/ce/ce204639…/request_headers 183 字节 s/ce/ce204639…/response_body 15 字节 s/ce/ce204639…/response_data 168 字节 s/ce/ce204639…/response_headers 94 字节 response_body = b'<html>ok</html>' response_headers 的头两行 = ['Content-Length: 15', 'Server: plab'] pickled_meta 里的键 = ['method', 'response_url', 'status', 'timestamp', 'url']
每个请求一个目录,里面分别存请求头体、响应头体、元数据和 pickle 的附加字段;文件名按请求指纹组织。
第二次运行服务器仍收到的路径:(无);stats {'hit': 8}
HTTPCACHE_IGNORE_HTTP_CODES=404,500:第二次运行服务器收到 ['/404', '/500', '/500', '/500'];stats {'firsthand': 4, 'hit': 4, 'miss': 4, 'uncacheable': 4}默认策略,不管状态码和 Cache-Control,全部缓存且永不过期,适合开发调试时反复回放。
第二次运行服务器收到的请求(及条件头):
/nostore If-None-Match=(无) If-Modified-Since=(无)
/etag If-None-Match="v1" If-Modified-Since=(无)
/ok If-None-Match=(无) If-Modified-Since=(无)
/lm If-None-Match=(无) If-Modified-Since=Mon, 01 Jan 2024 00:00:00 GMT
stats {'firsthand': 2, 'hit': 1, 'miss': 2, 'revalidate': 2, 'store': 2, 'uncacheable': 2}
回调:/etag status=200 flags=['cached'] body='<html>etag body</htm'
回调:/lm status=200 flags=['cached'] body='<html>lm</html>'
回调:/maxage status=200 flags=['cached'] body='<html>ma</html>'
回调:/nostore status=200 flags=[] body='<html>ns</html>'
回调:/ok status=200 flags=[] body='<html>ok</html>'按 HTTP 缓存规则:no-store 不缓存,max-age 内直接命中,过期后用 ETag / Last-Modified 做条件请求,304 则复用缓存正文。
立即再跑:服务器收到 0 个;{'hit': 1}
3 秒后再跑:服务器收到 1 个;{'firsthand': 1, 'miss': 1, 'store': 1}HTTPCACHE_EXPIRATION_SECS 控制过期,HTTPCACHE_IGNORE_HTTP_CODES 排除某些状态码,meta dont_cache 跳过单个请求。
dont_cache=True:服务器收到 1 个;{}
HTTPCACHE_IGNORE_MISSING=1:服务器收到 0 个;{'hit': 1, 'ignore': 1, 'miss': 1};回调 ['/ok'],错误 [('/never-seen', 'IgnoreRequest')]HTTPCACHE_IGNORE_MISSING 让缓存里没有的请求直接被忽略,可以用来离线重放。
第二次运行服务器已关闭:stats {'errorrecovery': 1, 'miss': 1};回调 [('/etag', 200, ['cached'])];错误 [('/ok', 'DownloadConnectionRefusedError')]下载异常时如果有旧缓存,会返回旧缓存并计入 httpcache/errorrecovery。