互联网工程任务组 (IETF) M. Nottingham
请求评议:5861 雅虎公司
类别:信息性 2010年5月
ISSN: 2070-1721

HTTP 缓存控制扩展:陈旧内容


摘要

本文档定义了两个独立的 HTTP Cache-Control 扩展,允许对缓存使用陈旧响应的行为进行控制。

本备忘录的状态

本文件不是互联网标准轨道规范;仅作为信息发布。

本文件是互联网工程任务组(IETF)的成果,代表 IETF 社区的共识。它已获得公开评审,并经互联网工程指导小组(IESG)批准发布。并非所有被 IESG 批准的文件都能成为互联网标准的候选文件;详见 RFC 5741 第2节

关于本文档当前状态、勘误及如何反馈信息,可访问 http://www.rfc-editor.org/info/rfc5861 获取。

Copyright Notice

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

1. 引言

HTTP [RFC2616] 要求缓存“以所持有的最新响应……来响应请求,该响应应与请求相符”,但“在经过严格控制的情况下”允许返回陈旧响应。本文档定义了两个独立的 Cache-Control 扩展,用于这种控制:stale-if-error 和 stale-while-revalidate。

stale-if-error HTTP Cache-Control 扩展允许当遇到错误(例如 500 内部服务器错误、网络分段或 DNS 失败)时,缓存返回陈旧响应,而不是返回“硬”错误。这提升了可用性。

stale-while-revalidate HTTP Cache-Control 扩展允许缓存后台重新验证的同时,立即返回陈旧响应,从而将客户端感知的延迟(无论是网络还是服务器端)隐藏起来。

2. 符号约定

本文件中的关键词 “MUST”(必须)、“MUST NOT”(禁止)、“REQUIRED”(需要)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(建议)、“SHOULD NOT”(不建议)、“RECOMMENDED”(推荐)、“MAY”(可以)以及 “OPTIONAL”(可选)应按照 RFC 2119 [RFC2119] 中的说明进行解释。

本规范使用 RFC2616 [RFC2616] 的扩展巴科斯-诺尔范式,并引入了该规范中的 delta-seconds 规则。

3. stale-while-revalidate 缓存控制扩展

当该扩展出现在 HTTP 响应中时,表示缓存可以在响应过期后,继续在规定秒数内提供该响应的陈旧版本。

  stale-while-revalidate = "stale-while-revalidate" "=" delta-seconds

如果由于此扩展的存在而提供了陈旧的缓存响应,缓存应在继续提供陈旧响应的同时尝试重新验证(即,不阻塞)。

注意,“陈旧”意味着响应将包含非零的 Age 首部和 warning 首部,符合 HTTP 的要求。

如果 delta-seconds 时间过去后缓存实体仍未被重新验证,除非有其他信息,否则不应继续以陈旧状态提供。

3.1. 示例

包含如下内容的响应:

  Cache-Control: max-age=600, stale-while-revalidate=30

表示内容在 600 秒内为新鲜,在异步验证期间还可继续以陈旧状态提供最多 30 秒。如果验证未果,或期间没有触发验证的流量,30 秒后 stale-while-revalidate 功能将停止,缓存响应变为“真正的”陈旧(即,下次请求会阻塞并按常规处理)。

通常,服务器会将 max-age 和 stale-while-revalidate 的组合设置为可容忍的最长总新鲜期。例如,两者都设为 600 时,服务器必须能够容忍响应最长被缓存服务 20 分钟。

由于异步验证只会在响应变为陈旧后且仍在 stale-while-revalidate 窗口内时发生,因此该窗口的大小和期间请求的发生概率决定了所有请求无延迟服务的可能性。如果窗口过小或流量过少,则部分请求会落在窗口之外,需要等待服务器验证缓存响应。

4. stale-if-error 缓存控制扩展

stale-if-error 缓存控制扩展指示当遇到错误时,可以使用缓存的陈旧响应来满足请求,无需考虑其他新鲜度信息。

  stale-if-error = "stale-if-error" "=" delta-seconds

作为请求的 Cache-Control 扩展使用时,其作用范围为该请求;作为响应的 Cache-Control 扩展使用时,其作用范围为与其对应的所有请求。

其值表明最大允许的陈旧时长;当缓存响应的陈旧时间超过该值时,除非有其他信息,不应再用该响应满足请求。

此处的“错误”指会导致返回 500、502、503 或 504 HTTP 响应状态码的任何情况。

注意,该指令不影响新鲜度;使用的陈旧缓存响应在发送时仍应被明确标记为陈旧(即,包含非零的 Age 首部和 warning 首部,符合 HTTP 要求)。

4.1. 示例

包含如下内容的响应:

  HTTP/1.1 200 OK
  Cache-Control: max-age=600, stale-if-error=1200
  Content-Type: text/plain
  
  success

表示内容在 600 秒内为新鲜,在变为陈旧后遇到错误时,还可再用 1200 秒。

因此,若缓存在 900 秒后尝试验证并遇到如下响应:

  HTTP/1.1 500 Internal Server Error
  Content-Type: text/plain
  
  failure

则可以返回之前的成功响应:

  HTTP/1.1 200 OK
  Cache-Control: max-age=600, stale-if-error=1200
  Age: 900
  Content-Type: text/plain
  
  succcess

当 age 超过 1800 秒(即陈旧 1200 秒后),缓存必须返回错误消息。

  HTTP/1.1 500 Internal Server Error
  Content-Type: text/plain
  
  failure

5. 安全性注意事项

stale-while-revalidate 扩展为源服务器提供了一种机制,可规定在特定条件下,缓存应提供陈旧内容,并期望后台重新验证缓存响应。建议此类验证应依赖于收到新的请求,以避免放大攻击(如部分预取和自动刷新机制中可能出现的)。缓存实现者应在决定哪些情况下生成非用户或客户端直接发起的请求时谨慎考虑。

stale-if-error 为源服务器和客户端提供了一种机制,可在特定条件下让缓存提供陈旧内容,其安全性不超出 RFC2616 的考虑范畴(RFC2616 也允许缓存提供陈旧内容)。

6. IANA 注意事项

本文档无须 IANA 采取任何操作。

附录 A. 致谢

感谢 Ben Drees、John Nienart、Henrik Nordstrom、Evan Torrie 和 Chris Westin 提出的建议。所有错误与疏漏由作者自行承担。

作者地址

Mark Nottingham
雅虎公司
电子邮箱: mnot@yahoo-inc.com
网址: http://www.mnot.net/