RFC7234: Hypertext Transfer Protocol (HTTP/1.1): Caching

Table of Contents

View Repo
                                                       PROPOSED STANDARD
                                                            Errata Exist
Internet Engineering Task Force (IETF)                  R. Fielding, Ed.
Request for Comments: 7234                                         Adobe
Obsoletes: 2616                                       M. Nottingham, Ed.
Category: Standards Track                                         Akamai
ISSN: 2070-1721                                          J. Reschke, Ed.
                                                              greenbytes
                                                               June 2014

摘要 / Abstract

The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document defines HTTP caches and the associated header fields that control cache behavior or indicate cacheable response messages.

超文本传输协议(HTTP)是一种无状态stateless的应用层协议,适用于分布式、协作式的超文本信息系统。本文档定义了 HTTP 的缓存以及相关的头字段,这些头字段负责控制缓存的行为,或者表明是一种可缓存cacheable的响应消息。

备忘状态 / Status of This Memo

This is an Internet Standards Track document.

这是一个 Internet Standards Track 文档。

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.

本文档是互联网工程任务组Internet Engineering Task Force(IETF)的产品。它代表了 IETF 社区的共识。它已经接受公众审核并且已经被互联网工程指导组Internet Engineering Steering Group(IESG)批准发布。有关互联网标准Internet Standards的更多信息,请参阅 RFC 5741 章节 2

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc7234.

关于本文档的当前状态,任何勘误以及如何提供反馈的信息可以从 http://www.rfc-editor.org/info/rfc7234 获得。

Copyright Notice

Copyright © 2014 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.

This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English.

1. 引言 / Introduction

HTTP is typically used for distributed information systems, where performance can be improved by the use of response caches. This document defines aspects of HTTP/1.1 related to caching and reusing response messages.

HTTP 通常用于分布式信息系统,通过使用响应缓存能够提升这些系统的性能。本文档定义了 HTTP/1.1 缓存响应消息以及复用响应消息相关的内容。

An HTTP cache is a local store of response messages and the subsystem that controls storage, retrieval, and deletion of messages in it. A cache stores cacheable responses in order to reduce the response time and network bandwidth consumption on future, equivalent requests. Any client or server MAY employ a cache, though a cache cannot be used by a server that is acting as a tunnel.

HTTP 缓存cache,是一种响应消息的本地存储,以及控制其内的消息的存储、获取和删除的子系统。缓存存储了可缓存的cacheable响应是为了减少将来的响应时间和网络带宽消耗。任何客户端或者服务器 可以 使用缓存,但是,当服务器作为隧道tunnel而使用时,不能使用缓存。

A shared cache is a cache that stores responses to be reused by more than one user; shared caches are usually (but not always) deployed as a part of an intermediary. A private cache, in contrast, is dedicated to a single user; often, they are deployed as a component of a user agent.

共享缓存shared cache是一种缓存,它存储响应用于给一个以上的用户来复用,通常(但并不总是)部署作为一个中间人的一部分。与之相对的是私有缓存private cache,这种缓存专门用于某一个用户,通常部署为一个用户代理的一个组件。

The goal of caching in HTTP/1.1 is to significantly improve performance by reusing a prior response message to satisfy a current request. A stored response is considered "fresh", as defined in Section 4.2, if the response can be reused without "validation" (checking with the origin server to see if the cached response remains valid for this request). A fresh response can therefore reduce both latency and network overhead each time it is reused. When a cached response is not fresh, it might still be reusable if it can be freshened by validation (Section 4.3) or if the origin is unavailable (Section 4.2.4).

在 HTTP/1.1 中,缓存通过复用一个之前的响应消息来满足当前的请求,其目的是显著提升性能。一个已存储的响应,如果它在不需要“验证”的情况就可以用来复用,那么,它被认为是“新鲜的fresh”(章节 4.2)。所谓“验证validation”,是指和源服务器一起检查,看看这个已存储的响应是否仍然有效于这个请求。因此,每一次复用一个新鲜的响应的时候,都可以减少双方的延迟以及网络开销。当一个已存储的响应不再新鲜,它可能仍旧可以获得复用,如果它可以通过验证(章节 4.3)而唤发新鲜freshened,或者原始的已不可用(章节 4.2.4)。

译注:本文所述的“验证”指的是“新鲜度验证”,也可以叫作“过期时间验证”。

1.1. 一致性和错误处理 / Conformance and Error Handling

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

本文档中的关键词 必须MUST禁止MUST NOT要求REQUIRED必须SHALL禁止SHALL NOT应当SHOULD不应当SHOULD NOT推荐RECOMMENDED可以MAY可选OPTIONAL 的意义与【RFC2119】一致。

Conformance criteria and considerations regarding error handling are defined in Section 2.5 of [RFC7230].

关于错误处理的一致性标准以及注意事项已在【RFC7230】章节 2.5 中定义了。

1.2. 句法标记 / Syntax Notation

This specification uses the Augmented Backus-Naur Form (ABNF) notation of [RFC5234] with a list extension, defined in Section 7 of [RFC7230], that allows for compact definition of comma-separated lists using a '#' operator (similar to how the '*' operator indicates repetition). Appendix B describes rules imported from other documents. Appendix C shows the collected grammar with all list operators expanded to standard ABNF notation.

本规范使用了扩展巴科斯范式Augmented Backus-Naur Form(ABNF)标记法【RFC5234】,另外,出于定义的紧凑性的考虑,本规范对 ABNF 规则进行了扩展(见章节 7),允许使用一个 # 操作符(类似于 * 操作符,指代“重复”)来定义一种以逗号分隔的列表。附录 B 描述了从其他文档中引进的规则。附录 C 展示了所有已收集的包含列表扩展规则以及标准 ABNF 标记的语法。

1.2.1. 秒差 / Delta Seconds

The delta-seconds rule specifies a non-negative integer, representing time in seconds.

delta-seconds 规则指定了一个非负整数来以秒数表示时间。

delta-seconds  = 1*DIGIT

A recipient parsing a delta-seconds value and converting it to binary form ought to use an arithmetic type of at least 31 bits of non-negative integer range. If a cache receives a delta-seconds value greater than the greatest integer it can represent, or if any of its subsequent calculations overflows, the cache MUST consider the value to be either 2147483648 (231) or the greatest positive integer it can conveniently represent.

接收端在解析一个 delta-seconds 值并将它转换为二进制形式binary form的时候,应该使用一种至少 31 位的非负整数范围的算术类型。如果一个缓存接收到一个 delta-seconds 的值大于缓存能够表示的最大整数,或者如果它接下来的任何运算出现数据溢出的情况,那么,缓存 必须 将该值视作 2147483648 (231) 或者视作它能够方便表示的最大正整数。

Note: The value 2147483648 is here for historical reasons, effectively represents infinity (over 68 years), and does not need to be stored in binary form; an implementation could produce it as a canned string if any overflow occurs, even if the calculations are performed with an arithmetic type incapable of directly representing that number. What matters here is that an overflow be detected and not treated as a negative value in later calculations.

注意: 这里的 2147483648 数值是出于历史的原因,有效地表示无限(超过 68 年),并且并不需要存储为二进制形式,也就是说,如果发生了任何溢出,HTTP 实现可以使用预制的字符串来产生这个值,即使执行运算的算术类型无法直接表示这个数值。重要的是检测到了一个数据溢出,并且在后续的运算当中没有将其作为一个负值来对待。

2. 缓存操作的概况 / Overview of Cache Operation

Proper cache operation preserves the semantics of HTTP transfers ([RFC7231]) while eliminating the transfer of information already held in the cache. Although caching is an entirely OPTIONAL feature of HTTP, it can be assumed that reusing a cached response is desirable and that such reuse is the default behavior when no requirement or local configuration prevents it. Therefore, HTTP cache requirements are focused on preventing a cache from either storing a non-reusable response or reusing a stored response inappropriately, rather than mandating that caches always store and reuse particular responses.

恰当的缓存操作可以在消除已存储在缓存中的消息的网络传输的同时还能保持 HTTP 传输的语义。虽然缓存是一种完全 可选的 HTTP 功能,但我们可以认为复用一个已缓存的响应是大家想要的,并且这样的复用行为是默认的(如果没有要求或本地配置阻止去缓存的话)。所以,HTTP 缓存的要求主要集中在阻止一个缓存去存储一个不可复用的响应,或者不恰当地复用一个已存储的响应这些方面;而不是在是否准许缓存总是存储并复用具体的响应。

Each cache entry consists of a cache key and one or more HTTP responses corresponding to prior requests that used the same key. The most common form of cache entry is a successful result of a retrieval request: i.e., a 200 (OK) response to a GET request, which contains a representation of the resource identified by the request target (Section 4.3.1 of [RFC7231]). However, it is also possible to cache permanent redirects, negative results (e.g., 404 (Not Found)), incomplete results (e.g., 206 (Partial Content)), and responses to methods other than GET if the method's definition allows such caching and defines something suitable for use as a cache key.

每个缓存条目cache entry是由一个缓存 key(映射键)以及一个或多个 HTTP 响应组成的,这些响应对应于之前有使用过相同的 key 的请求。缓存条目最常见的形式是一个检索请求(【RFC7231】章节 4.3.1)的成功返回结果,比如,一个回应给 GET 请求的 200 (OK) 响应。这种成功返回结果包含了一个由请求目标所标识的资源表示形式。但是,它同样可能去缓存一个永久重定向(301,见【RFC7231】章节 6.4.2)、否定的结果(比如,404 (Not Found))、不完整的结果(比如,206 (Partial Content))、以及回应给非 GET 方法的响应(如果方法的定义允许这种缓存行为并定义了某种适合用作一个缓存 key 的东西)。

The primary cache key consists of the request method and target URI. However, since HTTP caches in common use today are typically limited to caching responses to GET, many caches simply decline other methods and use only the URI as the primary cache key.

主要的缓存 key 是由请求方法request method以及目标 URI 组成的。但是,因为如今普遍使用的 HTTP 缓存通常都被限制为只对 GET 的响应进行缓存,因此,许多缓存简单地拒绝其他方法,并只使用 URI 作为主要的缓存 key。

If a request target is subject to content negotiation, its cache entry might consist of multiple stored responses, each differentiated by a secondary key for the values of the original request's selecting header fields (Section 4.1).

如果请求目标受到内容协商content negotiation的影响,那么它的缓存条目可能是由多个已存储的响应来组成的,每一个响应由一个次要的 key 来进行区分,这个次要的 key 的值是原始请求选定的头字段(章节 4.1)。

3. 将响应存储到缓存 / Storing Responses in Caches

A cache MUST NOT store a response to any request, unless:

  • The request method is understood by the cache and defined as being cacheable, and
  • the response status code is understood by the cache, and
  • the "no-store" cache directive (see Section 5.2) does not appear in request or response header fields, and
  • the "private" response directive (see Section 5.2.2.6) does not appear in the response, if the cache is shared, and
  • the Authorization header field (see Section 4.2 of [RFC7235]) does not appear in the request, if the cache is shared, unless the response explicitly allows it (see Section 3.2), and
  • the response either:
    • contains an Expires header field (see Section 5.3), or
    • contains a max-age response directive (see Section 5.2.2.8), or
    • contains a s-maxage response directive (see Section 5.2.2.9) and the cache is shared, or
    • contains a Cache Control Extension (see Section 5.2.3) that allows it to be cached, or
    • has a status code that is defined as cacheable by default (see Section 4.2.2), or
    • contains a public response directive (see Section 5.2.2.5).

除了可以存储回应给以下请求的响应以外,缓存 禁止 存储任何响应:

  • 请求方法request method为缓存所理解,并被定义为可缓存的cacheable,并且:
  • 响应状态码response status code为缓存所理解,并且:
  • no-store 缓存指令cache directive章节 5.2)没有出现在请求或者响应的头字段里,并且:
  • private 响应指令(章节 5.2.2.6)没有出现在响应里,如果这是个共享缓存的话,并且:
  • Authorization 头字段(【RFC7235】章节 4.2)没有出现在请求里,如果这是个共享缓存的话,除非响应明确允许它(章节 3.2),并且:
  • 响应符合以下情况之一:
    • 包含一个 Expires 头字段(章节 5.3),或者:
    • 包含一个 max-age 响应指令(章节 5.2.2.8),或者:
    • 包含一个 s-maxage 响应指令(章节 5.2.2.9)并且缓存是共享的,或者:
    • 包含一个缓存控制扩展Cache Control Extension章节 5.2.3),该缓存控制扩展允许缓存这个响应,或者:
    • 带有一个状态码,该状态码默认是可缓存的(章节 4.2.2),或者:
    • 包含一个 public 响应指令(章节 5.2.2.5)。

Note that any of the requirements listed above can be overridden by a cache-control extension; see Section 5.2.3.

需要注意的是,上述所列出的任何要求都可以被 cache-control 扩展所覆盖,见章节 5.2.3

In this context, a cache has "understood" a request method or a response status code if it recognizes it and implements all specified caching-related behavior.

在这个场景中,一个缓存已经“理解”一个请求方法或者一个响应状态码,指的是缓存可以识别到它并实现了所有缓存相关的行为。

Note that, in normal operation, some caches will not store a response that has neither a cache validator nor an explicit expiration time, as such responses are not usually useful to store. However, caches are not prohibited from storing such responses.

需要注意的是,在常规操作中,如果一个响应既没有缓存验证器cache validator也没有一个明确过期时间explicit expiration time,某些缓存将不会存储这种响应,因为存储这种响应通常是没有用处的。但是,缓存不会被禁止存储这种响应。

3.1. 存储不完整的响应 / Storing Incomplete Responses

A response message is considered complete when all of the octets indicated by the message framing ([RFC7230]) are received prior to the connection being closed. If the request method is GET, the response status code is 200 (OK), and the entire response header section has been received, a cache MAY store an incomplete response message body if the cache entry is recorded as incomplete. Likewise, a 206 (Partial Content) response MAY be stored as if it were an incomplete 200 (OK) cache entry. However, a cache MUST NOT store incomplete or partial-content responses if it does not support the Range and Content-Range header fields or if it does not understand the range units used in those fields.

在连接被关闭之前,所有由消息分帧message framing(【RFC7230】)所表明的字节octets都已被接收到,那么,这个响应消息被认为是完整的complete。如果请求方法是 GET,响应状态码是 200 (OK),并且整个响应头部response header section都已经被接收到,那么,缓存 可以 存储一个不完整incomplete响应消息体response message body,如果对应的缓存条目是被记录为不完整的话。同样,一个 206 (Partial Content) 响应 可以 被缓存作为一个不完整的 200 (OK) 的缓存条目。但是,如果缓存并不支持 RangeContent-Range 头字段,或者它并不理解用在这些头字段中的范围单位range unit,那么,缓存 禁止 存储不完整incomplete的或者部分内容partial-content的响应。

A cache MAY complete a stored incomplete response by making a subsequent range request ([RFC7233]) and combining the successful response with the stored entry, as defined in Section 3.3. A cache MUST NOT use an incomplete response to answer requests unless the response has been made complete or the request is partial and specifies a range that is wholly within the incomplete response. A cache MUST NOT send a partial response to a client without explicitly marking it as such using the 206 (Partial Content) status code.

缓存 可以 通过发起后续范围请求range request(【RFC7233】)并将成功响应successful response和已存储的条目进行结合,来使一个已存储的不完整响应补充完整,正如章节 3.3 所定义的。缓存 禁止 使用一个不完整响应来回应请求,除非这个响应已被补充完整,或者这个请求是一个部分请求partial request并指定了一个范围且这个范围统统在该不完整响应以内。对于没有明确地使用 206 (Partial Content) 状态码进行标记的部分响应partial response,缓存 禁止 发送这种部分响应partial response到一个客户端。

3.2. 存储回应给认证请求的响应 / Storing Responses to Authenticated Requests

A shared cache MUST NOT use a cached response to a request with an Authorization header field (Section 4.2 of [RFC7235]) to satisfy any subsequent request unless a cache directive that allows such responses to be stored is present in the response.

如果共享缓存所缓存的一个响应的 key 对应于一个带有 Authorization 头字段(【RFC7235】章节 4.2)的请求,那么,共享缓存 禁止 使用这个已缓存的响应来满足任何后续的请求,除非这个响应里出现了一个缓存指令,该指令允许这个响应被存储。

In this specification, the following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage.

在本规范中,以下 Cache-Control 响应指令(章节 5.2.2)有上述这种影响:must-revalidatepublic、以及 s-maxage

Note that cached responses that contain the "must-revalidate" and/or "s-maxage" response directives are not allowed to be served stale (Section 4.2.4) by shared caches. In particular, a response with either "max-age=0, must-revalidate" or "s-maxage=0" cannot be used to satisfy a subsequent request without revalidating it on the origin server.

需要注意的是,如果已缓存的响应包含有 must-revalidate 并且/或者 s-maxage 响应指令,那么,这些缓存响应是不允许被共享缓存用来提供陈旧响应serve stale的(章节 4.2.4)。实践中,一个响应,如果它带有 max-age=0, must-revalidate,或者带有 s-maxage=0,那么,在没有经过源服务器重新验证revalidating的情况下,它是不能用来满足后续请求的。

译注:所谓 "serve stale",指的是:提供陈旧的缓存响应来作为响应,即使这个已缓存的响应已经过期。对于一个请求,当对应的已缓存的响应已经过期(stale),并且源服务器无响应或者响应一个错误,这时候,缓存服务器返回这个 stale 的响应来作为回应,而不是返回错误。在大多数情况下,与其响应超时或返回其他错误,倒不如返回给用户一个能用的但过期的响应。

3.3. 结合部分内容 / Combining Partial Content

A response might transfer only a partial representation if the connection closed prematurely or if the request used one or more Range specifiers ([RFC7233]). After several such transfers, a cache might have received several ranges of the same representation. A cache MAY combine these ranges into a single stored response, and reuse that response to satisfy later requests, if they all share the same strong validator and the cache complies with the client requirements in Section 4.3 of [RFC7233].

如果连接被过早地关闭了,或者请求使用了一个或多个 Range 规格,那么,一个响应可能只传输一个表示形式的一部分(【RFC7233】)。历经多次这样的传输以后,缓存可能已接收到同一个表示形式的许多范围。缓存 可以 将这些范围合并为单个已存储的响应,并复用这个响应来满足接下来的请求,如果这些请求都共享同一个强验证器,并且缓存遵从【RFC7233】章节 4.3 对于客户端方面的要求的话。

When combining the new response with one or more stored responses, a cache MUST:

  • delete any Warning header fields in the stored response with warn-code 1xx (see Section 5.5);
  • retain any Warning header fields in the stored response with warn-code 2xx; and,
  • use other header fields provided in the new response, aside from Content-Range, to replace all instances of the corresponding header fields in the stored response.

当将一个或多个已存储的响应结合成一个新的响应的时候,缓存 必须 对这个新响应做如下处理:

  • 删除在已存储的响应里警告码为 1xx 的任何 Warning 头字段(见章节 5.5);
  • 保留在已存储的响应里警告码为 2xx 的任何 Warning 头字段;并且
  • 使用新响应所提供的其他头字段,除以 Content-Range 以外,来替换所有在已存储的响应中对应的头字段。

4. 从缓存中构造响应 / Constructing Responses from Caches

When presented with a request, a cache MUST NOT reuse a stored response, unless:

  • The presented effective request URI (Section 5.5 of [RFC7230]) and that of the stored response match, and
  • the request method associated with the stored response allows it to be used for the presented request, and
  • selecting header fields nominated by the stored response (if any) match those presented (see Section 4.1), and
  • the presented request does not contain the no-cache pragma (Section 5.4), nor the no-cache cache directive (Section 5.2.1), unless the stored response is successfully validated (Section 4.3), and
  • the stored response does not contain the no-cache cache directive (Section 5.2.2.2), unless it is successfully validated (Section 4.3), and
  • the stored response is either:

当面临一个请求的时候,缓存 禁止 复用一个已存储的响应,除非:

  • 所面临的实际请求 URIeffective request URI【RFC7230】章节 5.5)与已存储的响应所对应的实际请求 URI 相匹配,并且:
  • 已存储的响应所关联的请求方法允许这个响应用于所面临的请求,并且:
  • 由已存储的响应所指定nominated的选择头字段与所面临的请求的头字段相匹配(章节 4.1),并且:
  • 所面临的请求并没有包含一个值为 no-cachePragma 头字段(章节 5.4),也没有包含一个值为 no-cache 的缓存指令(章节 5.2.1),除非已存储的响应是被成功验证的successfully validated章节 4.3),并且:
  • 已存储的响应并没有包含一个 no-cache 缓存指令(章节 5.2.2.2),除非它是被成功验证的(章节 4.3),并且:
  • 已存储的响应是以下情况之一:

译注:所谓“成功验证successfully validated”,指的是源服务器确认了这个被缓存所存储的响应的仍然新鲜,可以继续用于响应请求。

Note that any of the requirements listed above can be overridden by a cache-control extension; see Section 5.2.3.

需要注意的是,上述所列出的任何要求都可以被 cache-control 扩展所覆盖,见章节 5.2.3

When a stored response is used to satisfy a request without validation, a cache MUST generate an Age header field (Section 5.1), replacing any present in the response with a value equal to the stored response's current_age; see Section 4.2.3.

在没有验证validation的情况下将一个已存储的响应用于满足一个请求时,缓存 必须 生成一个 Age 头字段(章节 5.1),其值等于已存储的响应的 current_age,来替换掉出现在该响应里的任何 Age 字段,见章节 4.2.3

A cache MUST write through requests with methods that are unsafe (Section 4.2.1 of [RFC7231]) to the origin server; i.e., a cache is not allowed to generate a reply to such a request before having forwarded the request and having received a corresponding response.

如果请求带有对源服务器来说是不安全的方法unsafe methods【RFC7231】章节 4.2.1),那么,缓存 必须 使用直写模式write through来写入请求,也就是说,在缓存已经转发这种请求并且已经接收到一个对应的响应之前,不允许缓存生成一个回复到这种请求上。

译注:缓存有两种基础写入策略:直写模式Write-through回写模式Write-back,详情见 Wikipedia: Cache - Writing Policies

Also, note that unsafe requests might invalidate already-stored responses; see Section 4.4.

另外,还需要注意的是,不安全的请求可能会使已经存储的响应置为无效,见章节 4.4

When more than one suitable response is stored, a cache MUST use the most recent response (as determined by the Date header field). It can also forward the request with "Cache-Control: max-age=0" or "Cache-Control: no-cache" to disambiguate which response to use.

当存储了超过一个以上的合适响应,缓存 必须 使用时间最近的响应(由 Date 头字段的时间来决定)。它还可以在转发这个请求的时候带上 Cache-Control: max-age=0 或者 Cache-Control: no-cache 以区分使用的是哪一个响应。

A cache that does not have a clock available MUST NOT use stored responses without revalidating them upon every use.

如果缓存不具有一个可用的时钟功能,那么,在每次使用已存储的响应的时候,禁止 在没有重新验证的情况下使用它们。

4.1. 使用 Vary 来计算次要缓存键 / Calculating Secondary Keys with Vary

When a cache receives a request that can be satisfied by a stored response that has a Vary header field (Section 7.1.4 of [RFC7231]), it MUST NOT use that response unless all of the selecting header fields nominated by the Vary header field match in both the original request (i.e., that associated with the stored response), and the presented request.

一个缓存,当它接收到一个请求,而这个请求可以通过一个已缓存的带有一个 Vary 头字段(【RFC7231】章节 7.1.4)的响应来满足,那么,它 禁止 使用这种响应,除非所有由 Vary 头字段所指定的选择头字段selecting header fields既与原始请求(即这个已存储响应所关联的那个请求)相匹配,也与所面临的请求相匹配。

The selecting header fields from two requests are defined to match if and only if those in the first request can be transformed to those in the second request by applying any of the following:

  • adding or removing whitespace, where allowed in the header field's syntax
  • combining multiple header fields with the same field name (see Section 3.2 of [RFC7230])
  • normalizing both header field values in a way that is known to have identical semantics, according to the header field's specification (e.g., reordering field values when order is not significant; case-normalization, where values are defined to be case-insensitive)

来自这两个请求的选择头字段selecting header fields是定义为相互匹配的,当且仅当在第一个请求的选择头字段,通过应用以下任何方式,能够转换为在第二个请求的选择头字段:

  • 在头字段的句法所允许的位置添加或删除空白
  • 合并多个相同字段名称的头字段(【RFC7230】章节 3.2
  • 依据头字段的规范,使用已知是具有同等语义的方式,来规范化两者的头字段值(比如,将头字段的值进行重新排序reordering,如果它的顺序并不重要的话;对于值是定义为不区分大小写的地方进行大小写规范化case-normalization)。

If (after any normalization that might take place) a header field is absent from a request, it can only match another request if it is also absent there.

如果(在进行过任何规范化操作以后)一个请求缺少某一个头字段,那么,它只能匹配上另一个同样缺少这个头字段的请求。

A Vary header field-value of "*" always fails to match.

值为 "*" 的 Vary 头字段总是无法匹配。

The stored response with matching selecting header fields is known as the selected response.

带有匹配上的选择头字段selecting header fields的已存储响应,被称为已选响应selected response

If multiple selected responses are available (potentially including responses without a Vary header field), the cache will need to choose one to use. When a selecting header field has a known mechanism for doing so (e.g., qvalues on Accept and similar request header fields), that mechanism MAY be used to select preferred responses; of the remainder, the most recent response (as determined by the Date header field) is used, as per Section 4.

如果有多个可用的已选响应(可能包括没有 Vary 头字段的响应),缓存将需要选择一个来使用。当一个选择头字段有已知的机制用于做这种选择的时候(比如,Accept 上的 qvalue 以及类似的请求头字段),这种机制 可以 被用来选择最优响应(可能多个)preferred responses。选择好最优响应以后,使用时间最近的那一个响应,见章节 4

If no selected response is available, the cache cannot satisfy the presented request. Typically, it is forwarded to the origin server in a (possibly conditional; see Section 4.3) request.

如果没有可用的已选响应,那么,缓存无法满足所面临的请求。通常,它会以一个(可能是条件化的,见章节 4.3)请求将其转发到源服务器。

4.2. 新鲜度 / Freshness

A fresh response is one whose age has not yet exceeded its freshness lifetime. Conversely, a stale response is one where it has.

新鲜的响应fresh response,是日期还没超过它的保鲜期freshness lifetime的一种响应。相反,陈旧的响应stale response,是日期已经超过它的保鲜期的一种响应。

A response's freshness lifetime is the length of time between its generation by the origin server and its expiration time. An explicit expiration time is the time at which the origin server intends that a stored response can no longer be used by a cache without further validation, whereas a heuristic expiration time is assigned by a cache when no explicit expiration time is available.

响应的保鲜期freshness lifetime是从它被源服务器生成开始到它的过期时间expiration time之间的时间长度。明确过期时间explicit expiration time,是源服务器打算让一个已存储的响应,在没有进一步的验证的情况下,不再能够被缓存所使用的那个时间点。与之相对,启发式过期时间heuristic expiration time,是当没有可用的明确过期时间explicit expiration time的时候由缓存所指派的过期时间。

译注:明确过期时间explicit expiration time启发式过期时间heuristic expiration time都是专业术语,下文会多次引用这两个术语。

A response's age is the time that has passed since it was generated by, or successfully validated with, the origin server.

一个响应的“年龄”指的是从它被源服务器生成开始,或者从它被源服务器成功验证开始,已经过去了多长时间。

When a response is "fresh" in the cache, it can be used to satisfy subsequent requests without contacting the origin server, thereby improving efficiency.

当一个响应在缓存中是“新鲜的”,那么,它能够被用于满足后续的请求,而不需要事先与源服务器取得联系。

The primary mechanism for determining freshness is for an origin server to provide an explicit expiration time in the future, using either the Expires header field (Section 5.3) or the max-age response directive (Section 5.2.2.8). Generally, origin servers will assign future explicit expiration times to responses in the belief that the representation is not likely to change in a semantically significant way before the expiration time is reached.

确定新鲜度的主要机制是源服务器提供一个未来的明确过期时间explicit expiration time,可以使用 Expires 头字段(章节 5.3)来提供,也可以使用 max-age 响应指令(章节 5.2.2.8)来提供。通常,源服务器会为响应指派一个未来的明确过期时间,认为在过期时间来临之前,表示形式不太可能会有语义上的重大变化。

If an origin server wishes to force a cache to validate every request, it can assign an explicit expiration time in the past to indicate that the response is already stale. Compliant caches will normally validate a stale cached response before reusing it for subsequent requests (see Section 4.2.4).

如果源服务器希望强制让缓存每一次请求都要向源服务器进行验证,那么,它可以指派一个过去的明确过期时间explicit expiration time,来表明这个响应已经是陈旧的stale。遵从规范的缓存将会在复用一个陈旧的已缓存的响应来满足后续请求之前,正常地验证它(见章节 4.2.4)。

Since origin servers do not always provide explicit expiration times, caches are also allowed to use a heuristic to determine an expiration time under certain circumstances (see Section 4.2.2).

因为源服务器并不总是会提供明确过期时间explicit expiration time的,因此,在某种情况下,规范还允许缓存使用启发式方法heuristic来确定一个过期时间(章节 4.2.2)。

The calculation to determine if a response is fresh is:

确定一个响应是否新鲜fresh的计算方法为:

response_is_fresh = (freshness_lifetime > current_age)

freshness_lifetime is defined in Section 4.2.1; current_age is defined in Section 4.2.3.

freshness_lifetime 定义在章节 4.2.1current_age 定义在章节 4.2.3

Clients can send the max-age or min-fresh cache directives in a request to constrain or relax freshness calculations for the corresponding response (Section 5.2.1).

客户端能够在请求中发送 max-age 或者 min-fresh 缓存指令来限制或放松对应响应的新鲜度计算(章节 5.2.1)。

When calculating freshness, to avoid common problems in date parsing:

  • Although all date formats are specified to be case-sensitive, a cache recipient SHOULD match day, week, and time-zone names case-insensitively.
  • If a cache recipient's internal implementation of time has less resolution than the value of an HTTP-date, the recipient MUST internally represent a parsed Expires date as the nearest time equal to or earlier than the received value.
  • A cache recipient MUST NOT allow local time zones to influence the calculation or comparison of an age or expiration time.
  • A cache recipient SHOULD consider a date with a zone abbreviation other than GMT or UTC to be invalid for calculating expiration.

当计算新鲜度的时候,为了避免日期解析的常见问题:

  • 虽然所有日期格式都被指定为区分大小写case-sensitive,但是,缓存接收端cache recipient 应当 使用不区分大小写case-insensitive的方式来匹配dayweek、以及时区time-zone的名称。
  • 如果缓存接收端关于时间的内部实现的精度低于 HTTP-date 的值的精度,那么,接收端 必须 以早于或等于所接收到的值的最接近的时间来内部表示一个解析过的 Expires
  • 缓存接收端 禁止 允许本地时区来影响年龄或过期时间age or expiration time的计算或对比。
  • 缓存接收端 应当 将一个带有时区缩写不是 GMT 或 UTC 的一个日期视为无效于过期时间计算。

Note that freshness applies only to cache operation; it cannot be used to force a user agent to refresh its display or reload a resource. See Section 6 for an explanation of the difference between caches and history mechanisms.

需要注意的是,新鲜度仅适用于缓存操作,它并不能被用于强制一个用户代理去刷新refresh它的展示或者重新加载reload一个资源。关于缓存与历史记录的机制的不同点的解释,见章节 6

4.2.1. 计算保鲜期 / Calculating Freshness Lifetime

A cache can calculate the freshness lifetime (denoted as freshness_lifetime) of a response by using the first match of the following:

  • If the cache is shared and the s-maxage response directive (Section 5.2.2.9) is present, use its value, or
  • If the max-age response directive (Section 5.2.2.8) is present, use its value, or
  • If the Expires response header field (Section 5.3) is present, use its value minus the value of the Date response header field, or
  • Otherwise, no explicit expiration time is present in the response. A heuristic freshness lifetime might be applicable; see Section 4.2.2.

缓存能够计算一个响应的保鲜期(表示为 freshness_lifetime),通过使用下列第一个能够匹配上的方式:

  • 如果缓存是共享的,并且响应中出现了 s-maxage 响应指令(章节 5.2.2.9),那么,使用这个指令的值,或者:
  • 如果响应中出现了 max-age 响应指令(章节 5.2.2.8),那么,使用这个指令的值,或者:
  • 如果响应中出现了 Expires 响应头字段(章节 5.3),那么,使用它的值减去 Date 响应头字段的值,或者:
  • 否则,响应中没有出现明确过期时间explicit expiration time。可能适用于一个启发式保鲜期,见章节 4.2.2

Note that this calculation is not vulnerable to clock skew, since all of the information comes from the origin server.

需要注意的是,这种计算是不会受到时钟偏差clock skew的影响的,这是因为所有的信息都是来自源服务器的。

When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives), the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale.

当一个给定的指令中出现超过一个以上的值(比如,有两个 Expires 头字段、多个 Cache-Control 指令等),那么,这个指令的值被视为无效的。规范鼓励缓存把带有无效的新鲜度信息的那种响应视为是陈旧的stale

4.2.2. 计算启发式新鲜度 / Calculating Heuristic Freshness

Since origin servers do not always provide explicit expiration times, a cache MAY assign a heuristic expiration time when an explicit time is not specified, employing algorithms that use other header field values (such as the Last-Modified time) to estimate a plausible expiration time. This specification does not provide specific algorithms, but does impose worst-case constraints on their results.

因为源服务器并不总是会提供明确过期时间explicit expiration time的,因此,当它没有指定一个过期时间的时候,缓存可以指派一个启发式过期时间heuristic expiration time,原理是利用一种使用其他头字段值来估算出一个看似合理的过期时间的算法。本规范并没有提供具体的算法,但是对它们的计算结果的最差情况实施了约束。

A cache MUST NOT use heuristics to determine freshness when an explicit expiration time is present in the stored response. Because of the requirements in Section 3, this means that, effectively, heuristics can only be used on responses without explicit freshness whose status codes are defined as cacheable by default (see Section 6.1 of [RFC7231]), and those responses without explicit freshness that have been marked as explicitly cacheable (e.g., with a "public" response directive).

当一个已存储的响应中出现了一个明确过期时间explicit expiration time的时候,缓存 禁止 使用启发式来确定新鲜度。由于章节 3 中的要求,这意味着,实际上,启发式仅能用于没有明确新鲜度的响应,并且要求以下情况之一:

  • 这些响应的状态码被定义为默认是可缓存的(见【RFC7231】章节 6.1);
  • 这些响应被明确标记为可缓存的(比如,带有一个 public 响应指定)。

If the response has a Last-Modified header field (Section 2.2 of [RFC7232]), caches are encouraged to use a heuristic expiration value that is no more than some fraction of the interval since that time. A typical setting of this fraction might be 10%.

如果响应带有一个 Last-Modified 头字段(【RFC7232】章节 2.2),规范鼓励缓存所使用的启发式过期时间的值不超过那个头字段的时间以后的某个比例,通常这个比例会设置为 10%

When a heuristic is used to calculate freshness lifetime, a cache SHOULD generate a Warning header field with a 113 warn-code (see Section 5.5.4) in the response if its current_age is more than 24 hours and such a warning is not already present.

当使用启发式来计算保鲜期freshness lifetime的时候,缓存 应当 在响应里生成一个 Warning 头字段,其值带有一个 113 警告码(见章节 5.5.4),如果这个响应的 current_age 大于 24 小时而且响应中还没有出现这种警告的话。

Note: Section 13.9 of [RFC2616] prohibited caches from calculating heuristic freshness for URIs with query components (i.e., those containing '?'). In practice, this has not been widely implemented. Therefore, origin servers are encouraged to send explicit directives (e.g., Cache-Control: no-cache) if they wish to preclude caching.

注意: 对于带有 query 组件的 URI(也就是说,包含有 "?" 的 URI),【RFC2616】章节 13.9 禁止缓存对这种 URI 计算启发式新鲜度。实践中,这项要求并未被广泛实现。因此,规范鼓励源服务器去发送明确的指令(比如,Cache-Control: no-cache),如果它们希望阻止缓存的话。

4.2.3. 计算年龄 / Calculating Age

The Age header field is used to convey an estimated age of the response message when obtained from a cache. The Age field value is the cache's estimate of the number of seconds since the response was generated or validated by the origin server. In essence, the Age value is the sum of the time that the response has been resident in each of the caches along the path from the origin server, plus the amount of time it has been in transit along network paths.

Age 头字段被用于运载一个估算的年龄,这个年龄表示从一个缓存中获得这个响应消息时,这个响应消息的年龄。Age 字段的值是从这个响应被源服务器所生成或所验证的那一时刻开始,直到缓存使用这个响应来满足请求为止,所经历的时间秒数的估算值。本质上,Age 的值是由下列时间构成:

  • 从源服务器开始,沿着响应消息的路径,响应消息驻留在每一个缓存节点里的时间之和,加上:
  • 响应消息沿着网络路径在各个节点间进行传输的总耗时。

译注:实际上,Age 值的计算并不是使用上述这些数据来生成,因为如果这样计算,就需要把响应在当前缓存节点的驻留时间加上所有上游缓存节点的驻留时间,还要加上各个节点间的传输时间,非常麻烦。

The following data is used for the age calculation:

age_value
The term "age_value" denotes the value of the Age header field (Section 5.1), in a form appropriate for arithmetic operation; or 0, if not available.
date_value
The term "date_value" denotes the value of the Date header field, in a form appropriate for arithmetic operations. See Section 7.1.1.2 of [RFC7231] for the definition of the Date header field, and for requirements regarding responses without it.
now
The term "now" means "the current value of the clock at the host performing the calculation". A host ought to use NTP ([RFC5905]) or some similar protocol to synchronize its clocks to Coordinated Universal Time.
request_time
The current value of the clock at the host at the time the request resulting in the stored response was made.
response_time
The current value of the clock at the host at the time the response was received.

以下数据用于计算年龄:

age_value
术语 age_value 表示 Age 头字段(章节 5.1)的值,以一种适合算术运算的形式来表示,其中,0 代表不可用。
date_value
术语 date_value 表示 Date 头字段的值,以一种适合算术运算的形式来表示。Date 头字段的定义,以及响应不带有这个字段时的相关要求,见【RFC7231】章节 7.1.1.2
now
术语 now 的含义是:在执行计算的时候,主机时钟的当前时间值。主机应该使用 NTP(【RFC5905】)或者某些类似的协议来同步它的时钟为 UTC 时间。
request_time
请求的发起时,主机时钟的当前时间值,这个请求会导致产生一个已存储的响应。
response_time
接收到响应时,主机时钟的当前时间值。

译注:

  • Date:表示响应消息在源服务器中诞生的时间,其值是一个 HTTP-date【RFC7231】章节 7.1.1.2)。
  • Age:表示已缓存的响应的年龄,即,从这个响应被源服务器所生成或所验证的那一时刻开始,直到缓存使用这个响应来满足请求为止,所经历的时间秒数的估算值,其值是一个秒数。

译注:nowrequest_time、以及 response_time 都是本地时间,虽然上述的“主机”指的是同一个缓存所在的主机,但由于 Date 是由服务器时间生成的,并且消息链路中可能出现多个缓存主机,这样就涉及到多个主机间的时钟可能不同步的问题,即时钟偏差clock skew,因此才需要使用 NTP 协议来同步时钟。

A response's age can be calculated in two entirely independent ways:

  1. the "apparent_age": response_time minus date_value, if the local clock is reasonably well synchronized to the origin server's clock. If the result is negative, the result is replaced by zero.
  2. the "corrected_age_value", if all of the caches along the response path implement HTTP/1.1. A cache MUST interpret this value relative to the time the request was initiated, not the time that the response was received.

一个响应的年龄可以使用两种完全独立的方式来计算出来:

  1. apparent_ageresponse_time 减去 date_value,如果本地时钟与源服务器的时候同步得相当好的话。如果计算结果为负数,则将其改为 0。
  2. corrected_age_value:如果响应消息沿路的所有缓存都实现了 HTTP/1.1,才适用这种方式。缓存 必须 相对于发起请求的时刻来解释这个值,而不是相对于接收到响应的时刻。
apparent_age = max(0, response_time - date_value);

response_delay = response_time - request_time;
corrected_age_value = age_value + response_delay;  

These are combined as

两种方式合并为:

corrected_initial_age = max(apparent_age, corrected_age_value);

unless the cache is confident in the value of the Age header field (e.g., because there are no HTTP/1.0 hops in the Via header field), in which case the corrected_age_value MAY be used as the corrected_initial_age.

除非缓存确信 Age 头字段的值(比如,因为 Via 头字段里没有任何 HTTP/1.0 的节点),在这种情况下,corrected_age_value 可以 作为 corrected_initial_age 来使用。

The current_age of a stored response can then be calculated by adding the amount of time (in seconds) since the stored response was last validated by the origin server to the corrected_initial_age.

然后,已存储的响应就可以计算出 current_age 了:通过把从这个已存储的响应最后一次被源服务器验证的时刻开始到现在为止所经历的总时长(秒),加入到 corrected_initial_age 上。

resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;

4.2.4. 提供陈旧的响应 / Serving Stale Responses

A "stale" response is one that either has explicit expiry information or is allowed to have heuristic expiry calculated, but is not fresh according to the calculations in Section 4.2.

一个 "stale"(陈旧的、不新鲜的)的响应是这样一种响应:或者带有明确的过期信息expiry information或者允许去进行启发式的过期计算expiry calculated,但根据章节 4.2 的计算,已不再新鲜fresh

A cache MUST NOT generate a stale response if it is prohibited by an explicit in-protocol directive (e.g., by a "no-store" or "no-cache" cache directive, a "must-revalidate" cache-response-directive, or an applicable "s-maxage" or "proxy-revalidate" cache-response-directive; see Section 5.2.2).

缓存 禁止 生成一个陈旧的响应stale response,如果它被一个明确的协议内的指令(比如,被一个 no-store 或者 no-cache 缓存指令cache directive、一个 must-revalidate 缓存响应指令cache-response-directive、或者一个适用的 s-maxage 或者 proxy-revalidate 缓存响应指令,见章节 5.2.2)所禁止的话。

A cache MUST NOT send stale responses unless it is disconnected (i.e., it cannot contact the origin server or otherwise find a forward path) or doing so is explicitly allowed (e.g., by the max-stale request directive; see Section 5.2.1).

缓存 禁止 发送陈旧的响应,除非它的连接被中断(也就是说,它不能够联系到源服务器或者找不到一个转发路径),或者被明确允许这样做(比如,通过 max-stale 请求指令,见章节 5.2.1)。

A cache SHOULD generate a Warning header field with the 110 warn-code (see Section 5.5.1) in stale responses. Likewise, a cache SHOULD generate a 112 warn-code (see Section 5.5.3) in stale responses if the cache is disconnected.

缓存 应当陈旧的响应stale responses中生成一个 Warning 头字段,其值带有一个 110 警告码(见章节 5.5.1)。同样,缓存 应当 在陈旧的响应中生成一个 112 警告码(见章节 5.5.3),如果缓存的连接被中断的话。

A cache SHOULD NOT generate a new Warning header field when forwarding a response that does not have an Age header field, even if the response is already stale. A cache need not validate a response that merely became stale in transit.

当缓存转发一个响应,但这个响应并没有一个 Age 头字段的时候,缓存 不应当 生成一个新的 Warning 头字段,即使这个响应已经是陈旧的。一个响应只在在传输过程中变成陈旧的,那么,缓存不需要验证这个响应。

4.3. 验证 / Validation

When a cache has one or more stored responses for a requested URI, but cannot serve any of them (e.g., because they are not fresh, or one cannot be selected; see Section 4.1), it can use the conditional request mechanism [RFC7232] in the forwarded request to give the next inbound server an opportunity to select a valid stored response to use, updating the stored metadata in the process, or to replace the stored response(s) with a new response. This process is known as "validating" or "revalidating" the stored response.

对于所请求的一个 URI,当缓存已经存储了这个 URI 对应的一个或多个响应,但缓存却不能使用它们之中的任何一个来满足这个请求(比如,因为它们都不再新鲜,或者没有一个可以选择的,见章节 4.1),这时候,缓存在转发这个请求时可以应用条件请求conditional request的机制【RFC7232】,给下一个入站服务器inbound server一个机会来选择一个有效的已存储的响应来使用,在这个过程中会更新已存储的元数据;或者使用一个新的响应到替换(可能是多个)已存储的响应。这个过程称为对已存储的响应进行“验证validating”或者“重新验证revalidating”。

译注:所谓“入站”,即数据流朝向源服务器流动,见【RFC7230】章节 2.3

4.3.1. 发送验证请求 / Sending a Validation Request

When sending a conditional request for cache validation, a cache sends one or more precondition header fields containing validator metadata from its stored response(s), which is then compared by recipients to determine whether a stored response is equivalent to a current representation of the resource.

当发送一个条件请求来进行缓存验证的时候,缓存发送一个或多个前提条件头字段来包含验证器元数据validator metadata,这些元数据来自(可能是多个)已存储的响应,然后,接收端会对比这些验证器,确定是否有一个已存储的响应等价于资源的一个当前表示形式。

One such validator is the timestamp given in a Last-Modified header field (Section 2.2 of [RFC7232]), which can be used in an If-Modified-Since header field for response validation, or in an If-Unmodified-Since or If-Range header field for representation selection (i.e., the client is referring specifically to a previously obtained representation with that timestamp).

Last-Modified 头字段(【RFC7232】章节 2.2)里给出的时间戳timestamp就是上述这些验证器中的一个,这个时间戳能够被用在 If-Modified-Since 头字段来验证响应,或者被用在 If-Unmodified-SinceIf-Range 头字段来选择表示形式(也就是说,客户端特指之前所获取到的带有那个时间戳的那一个表示形式)。

Another validator is the entity-tag given in an ETag header field (Section 2.3 of [RFC7232]). One or more entity-tags, indicating one or more stored responses, can be used in an If-None-Match header field for response validation, or in an If-Match or If-Range header field for representation selection (i.e., the client is referring specifically to one or more previously obtained representations with the listed entity-tags).

另一个验证器是 ETag 头字段(【RFC7232】章节 2.3)里给出的实体标签entity-tag。一个或多个实体标签,表明一个或多个已存储的响应,能够被用在 If-None-Match 头字段来验证响应,或者被用在 If-MatchIf-Range 头字段来选择表示形式(也就是说,客户端特指之前所获取到的带有这些实体标签的那一个或多个表示形式)。

4.3.2. 处理接收到的验证请求 / Handling a Received Validation Request

Each client in the request chain may have its own cache, so it is common for a cache at an intermediary to receive conditional requests from other (outbound) caches. Likewise, some user agents make use of conditional requests to limit data transfers to recently modified representations or to complete the transfer of a partially retrieved representation.

在请求链路中的每一个客户端都可能有自己的缓存,所以,一个中间人缓存接收到来自其他的(出站outbound)缓存的条件请求conditional requests是很常见的。同样,某些用户代理利用条件请求来对数据传输限制为最近修改过的表示形式,或者限制为完成一个只接收到部分的表示形式的传输。

译注:所谓“出站”,即数据流朝向客户端流动,见【RFC7230】章节 2.3

If a cache receives a request that can be satisfied by reusing one of its stored 200 (OK) or 206 (Partial Content) responses, the cache SHOULD evaluate any applicable conditional header field preconditions received in that request with respect to the corresponding validators contained within the selected response. A cache MUST NOT evaluate conditional header fields that are only applicable to an origin server, found in a request with semantics that cannot be satisfied with a cached response, or applied to a target resource for which it has no stored responses; such preconditions are likely intended for some other (inbound) server.

如果一个缓存接收到一个请求,而它能够通过复用它已存储的其中一个 200 (OK)206 (Partial Content) 响应来满足这个请求,那么,这个缓存 应当 在包含在已选响应selected response章节 4.1)中的验证器方面,对接收自那个请求中的对应的任何适用的条件请求头字段conditional header field的前提条件进行求值evaluate。缓存 禁止 对以下条件头字段进行求值:只适用于源服务器的头字段;在请求中找到的,但语义不能使用一个已缓存的响应来满足的头字段;或者应用于目标资源的头字段,因为这个缓存没有已存储的响应——上述这些前提条件可能是用于某些其他(入站inbound)服务器的。

The proper evaluation of conditional requests by a cache depends on the received precondition header fields and their precedence, as defined in Section 6 of [RFC7232]. The If-Match and If-Unmodified-Since conditional header fields are not applicable to a cache.

缓存如何正确对条件请求进行求值evaluation,依赖于其接收到的前提条件头字段以及它们的优先级,正如【RFC7232】章节 6 所定义的。If-MatchIf-Unmodified-Since 条件头字段并不适用于缓存。

A request containing an If-None-Match header field (Section 3.2 of [RFC7232]) indicates that the client wants to validate one or more of its own stored responses in comparison to whichever stored response is selected by the cache. If the field-value is "*", or if the field-value is a list of entity-tags and at least one of them matches the entity-tag of the selected stored response, a cache recipient SHOULD generate a 304 (Not Modified) response (using the metadata of the selected stored response) instead of sending that stored response.

一个请求,如果它包含有一个 If-None-Match 头字段(【RFC7232】章节 3.2),则表明:客户端想通过与缓存选定的任何已存储的响应相比较的方式,来验证客户端所拥有的一个或多个已存储的响应。如果它的字段值是 "*",或者它的字段值是一个实体标签列表并且至少其中之一个与已选的已存储的响应selected stored response相匹配,那么,缓存接收端 应当 生成一个 304 (Not Modified) 响应(使用那个已选的已存储的响应的元数据),而不是发送那个已存储的响应。

When a cache decides to revalidate its own stored responses for a request that contains an If-None-Match list of entity-tags, the cache MAY combine the received list with a list of entity-tags from its own stored set of responses (fresh or stale) and send the union of the two lists as a replacement If-None-Match header field value in the forwarded request. If a stored response contains only partial content, the cache MUST NOT include its entity-tag in the union unless the request is for a range that would be fully satisfied by that partial stored response. If the response to the forwarded request is 304 (Not Modified) and has an ETag header field value with an entity-tag that is not in the client's list, the cache MUST generate a 200 (OK) response for the client by reusing its corresponding stored response, as updated by the 304 response metadata (Section 4.3.4).

一个请求,其包含有一个 If-None-Match 头字段,字段值是实体标签的一个列表,当一个缓存决定为这个请求重新验证它所拥有的已存储的响应的时候,缓存 可以 将所接收到的列表与它所拥有的已存储的响应集合(新鲜的或陈旧的)的实体标签列表合并成一个列表,然后将这个联合列表代替到将要转发的请求的 If-None-Match 头字段值进行发送。如果某个已存储的响应包含的仅为表示形式的一部分内容partial content,那么,缓存 禁止 将这个响应的实体标签包含进联合列表中,除非这个请求是一个范围请求且请求的范围可以被那个已存储的部分响应完全满足。如果转发请求后返回的是一个 304 (Not Modified) 响应,并且这个响应有一个 ETag 头字段值,字段值有一个实体标签没有出现在客户端所请求的实体标签列表中,那么,客户端 必须 通过复用这个实体标签所对应的已存储的响应来为这个客户生成一个 200 (OK) 响应,同时将刚才返回的那个 304 响应的元数据更新到这个 200 响应中去(章节 4.3.4)。

If an If-None-Match header field is not present, a request containing an If-Modified-Since header field (Section 3.3 of [RFC7232]) indicates that the client wants to validate one or more of its own stored responses by modification date. A cache recipient SHOULD generate a 304 (Not Modified) response (using the metadata of the selected stored response) if one of the following cases is true: 1) the selected stored response has a Last-Modified field-value that is earlier than or equal to the conditional timestamp; 2) no Last-Modified field is present in the selected stored response, but it has a Date field-value that is earlier than or equal to the conditional timestamp; or, 3) neither Last-Modified nor Date is present in the selected stored response, but the cache recorded it as having been received at a time earlier than or equal to the conditional timestamp.

一个请求,如果没有出现 If-None-Match 头字段,而是包含有一个 If-Modified-Since 头字段(【RFC7232】章节 3.3),则表明:客户端想通过修改日期modification date来验证客户端所拥有的一个或多个已存储的响应。缓存接收端 应当 生成一个 304 (Not Modified) 响应(使用那个已选的已存储的响应的元数据),如果以下其中一种情况为真的话:

  1. 已选的已存储的响应有一个 Last-Modified 头字段,其值早于或等于条件式(即 If-Modified-Since)的时间戳。
  2. 已选的已存储的响应没有出现 Last-Modified 头字段,但它有一个 Date 头字段,其值早于或等于条件式的时间戳。
  3. 已选的已存储的响应既没有出现 Last-Modified 头字段,也没有出现 Date 头字段,但缓存记录到接收到这个响应的时间早于或等于条件式的时间戳。

A cache that implements partial responses to range requests, as defined in [RFC7233], also needs to evaluate a received If-Range header field (Section 3.2 of [RFC7233]) with respect to its selected stored response.

一个缓存,如果它还实现了对于范围请求的部分响应,正如【RFC7233】所定义的,还需要在它的已选的已存储的响应方面,对所接收到的 If-Range 头字段(【RFC7233】章节 3.2)进行求值。

4.3.3. 处理验证响应 / Handling a Validation Response

Cache handling of a response to a conditional request is dependent upon its status code:

  • A 304 (Not Modified) response status code indicates that the stored response can be updated and reused; see Section 4.3.4.
  • A full response (i.e., one with a payload body) indicates that none of the stored responses nominated in the conditional request is suitable. Instead, the cache MUST use the full response to satisfy the request and MAY replace the stored response(s).
  • However, if a cache receives a 5xx (Server Error) response while attempting to validate a response, it can either forward this response to the requesting client, or act as if the server failed to respond. In the latter case, the cache MAY send a previously stored response (see Section 4.2.4).

对于回应给条件请求的响应,缓存依据响应的状态码来进行处理:

  • 一个 304 (Not Modified) 响应状态码表明:缓存可以更新及复用这个已缓存的响应,见章节 4.3.4
  • 一个完全的响应full response(即,一个带有有效载荷payload body的响应)表明:没有任何一个已存储的响应适用于回应这个条件请求。而是,缓存 必须 使用这个完全的响应来满足这个请求,并且 可以 将(可能是多个)已存储的响应替换为这个完全的响应。
  • 然而,如果缓存在试图去验证响应的时候,接收到一个 5xx (Server Error) 响应,那么,它既可以转发这个响应给客户端,也可以将这种情况当作服务器响应出错failed to respond来处理。对于后者,缓存 可以 发送一个之前已存储的响应(见章节 4.2.4)。

4.3.4. 依据验证结果使已存储的响应唤发新鲜 / Freshening Stored Responses upon Validation

When a cache receives a 304 (Not Modified) response and already has one or more stored 200 (OK) responses for the same cache key, the cache needs to identify which of the stored responses are updated by this new response and then update the stored response(s) with the new information provided in the 304 response.

当一个缓存接收到一个 304 (Not Modified) 响应,并且对于这个响应所对应的缓存 key,缓存已经有一个或多个已存储的 200 (OK) 响应,那么,这个缓存需要去标识出哪些已缓存的响应需要被这个新响应所更新,然后使用提供自 304 响应的新信息更新它们。

The stored response to update is identified by using the first match (if any) of the following:

  • If the new response contains a strong validator (see Section 2.1 of [RFC7232]), then that strong validator identifies the selected representation for update. All of the stored responses with the same strong validator are selected. If none of the stored responses contain the same strong validator, then the cache MUST NOT use the new response to update any stored responses.
  • If the new response contains a weak validator and that validator corresponds to one of the cache's stored responses, then the most recent of those matching stored responses is selected for update.
  • If the new response does not include any form of validator (such as in the case where a client generates an If-Modified-Since request from a source other than the Last-Modified response header field), and there is only one stored response, and that stored response also lacks a validator, then that stored response is selected for update.

通过使用下列第一个能够匹配上(如果能的话)的方式,来标识出哪些已存储的响应需要被更新:

  • 如果新响应包含有一个强验证器strong validator(【RFC7232】章节 2.1),那么,那个强验证器标识了用于更新的已选表示形式。带有同一个强验证器的所有已存储的响应都被选中。如果已缓存的响应没有一个包含同一个强验证器,那么,缓存 禁止 使用新响应去更新任何一个已存储的响应。
  • 如果新响应包含有一个弱验证器weak validator对应上缓存的已存储的响应中的某一个验证器,那么,这些匹配上的已存储的响应中时间最新近的那一个会被选中用于更新。
  • 如果新响应并没有包含任何形式的验证器(比如一个客户端生成了一个 If-Modified-Since 请求,但生成来源并不是 Last-Modified 响应头字段这种情况),并且缓存只有一个已存储的响应,并且那个已存储的响应同样缺少验证器,那么,这个已存储的响应被选中用于更新。

If a stored response is selected for update, the cache MUST:

  • delete any Warning header fields in the stored response with warn-code 1xx (see Section 5.5);
  • retain any Warning header fields in the stored response with warn-code 2xx; and,
  • use other header fields provided in the 304 (Not Modified) response to replace all instances of the corresponding header fields in the stored response.

如果一个已存储的响应被选中用于更新,缓存 必须

  • 删除已存储的响应中的任何带有警告码为 1xxWarning 头字段(见章节 5.5);
  • 保留已存储的响应中的任何带有警告码为 2xxWarning 头字段;并且:
  • 使用 304 (Not Modified) 响应所提供的其他头字段,来替换所有在已存储的响应中对应的头字段。

4.3.5. 经由 HEAD 请求使用响应唤发新鲜 / Freshening Responses via HEAD

A response to the HEAD method is identical to what an equivalent request made with a GET would have been, except it lacks a body. This property of HEAD responses can be used to invalidate or update a cached GET response if the more efficient conditional GET request mechanism is not available (due to no validators being present in the stored response) or if transmission of the representation body is not desired even if it has changed.

回应给 HEAD 方法的响应与回应给一个等价的 GET 方法的响应是相同的,除了它缺少一个消息体以外。HEAD 响应的这种性质能够用来失效或更新一个已缓存的 GET 响应,如果更高效的条件 GET 请求机制不可用的话(由于没有验证器出现在已存储的响应),或者如果不期望传输带有表示形式的消息体(即使它已经改变)。

When a cache makes an inbound HEAD request for a given request target and receives a 200 (OK) response, the cache SHOULD update or invalidate each of its stored GET responses that could have been selected for that request (see Section 4.1).

当一个缓存对一个给定的请求目标发起一个入站inbound HEAD 请求,并接收到一个 200 (OK) 响应,那么,这个缓存 应当 更新或失效它所存储的每一个原本可以被那个请求选择的 GET 响应(见章节 4.1)。

For each of the stored responses that could have been selected, if the stored response and HEAD response have matching values for any received validator fields (ETag and Last-Modified) and, if the HEAD response has a Content-Length header field, the value of Content-Length matches that of the stored response, the cache SHOULD update the stored response as described below; otherwise, the cache SHOULD consider the stored response to be stale.

对于每一个原本可以被选择的已存储的响应来说,如果已存储的响应与 HEAD 响应的任何接收到的验证器头字段validator header fieldsETagLast-Modified)的值都已经相互匹配上,并且,如果 HEAD 响应带有一个 Content-Length 头字段,其字段值与已存储的响应的 Content-Length 头字段的值相匹配,那么,缓存 应当 像上述那样更新那个已存储的响应;否则,缓存 应当 将那个已存储的响应视为陈旧的stale

If a cache updates a stored response with the metadata provided in a HEAD response, the cache MUST:

  • delete any Warning header fields in the stored response with warn-code 1xx (see Section 5.5);
  • retain any Warning header fields in the stored response with warn-code 2xx; and,
  • use other header fields provided in the HEAD response to replace all instances of the corresponding header fields in the stored response and append new header fields to the stored response's header section unless otherwise restricted by the Cache-Control header field.

如果一个缓存使用 HEAD 响应所提供的元数据来更新一个已存储的响应的话,缓存 必须

  • 删除已存储的响应中的任何带有警告码为 1xxWarning 头字段(见章节 5.5);
  • 保留已存储的响应中的任何带有警告码为 2xxWarning 头字段;并且:
  • 使用 HEAD 响应所提供的其他头字段,来替换所有在已存储的响应中对应的头字段,并将新的头字段附加到已存储的响应的头部中去,除非 Cache-Control 头字段另有限制。

4.4. 失效 / Invalidation

Because unsafe request methods (Section 4.2.1 of [RFC7231]) such as PUT, POST or DELETE have the potential for changing state on the origin server, intervening caches can use them to keep their contents up to date.

因为像 PUT、POST、DELETE 等这些不安全的请求方法(【RFC7231】章节 4.2.1)可能会改变源服务器上的资源的状态,链路之间的缓存可以使用它们来保持它们的内容为最新。

A cache MUST invalidate the effective Request URI (Section 5.5 of [RFC7230]) as well as the URI(s) in the Location and Content-Location response header fields (if present) when a non-error status code is received in response to an unsafe request method.

当响应中带有一个非错误的状态码non-error status code,而这个响应是回应给一个不安全的请求方法的,那么,缓存 必须 失效invalidate实际请求 URIeffective Request URI【RFC7230】章节 5.5)以及在 LocationContent-Location 响应头字段(如果有出现的话)中的 URI。

However, a cache MUST NOT invalidate a URI from a Location or Content-Location response header field if the host part of that URI differs from the host part in the effective request URI (Section 5.5 of [RFC7230]). This helps prevent denial-of-service attacks.

但是,如果 Location 或者 Content-Location 响应头字段中的 URI 的 host 部分不同于有效请求 URI(【RFC7230】章节 5.5)中的 host 部分的话,缓存 禁止 失效这种 URI。这样做有助于避免拒绝服务攻击denial-of-service attacks

A cache MUST invalidate the effective request URI (Section 5.5 of [RFC7230]) when it receives a non-error response to a request with a method whose safety is unknown.

当缓存接收到一个非错误的回应non-error response,而这个响应是回应给一个请求方法的安全性是未知的请求的,那么,缓存 必须 失效有效请求 URI(【RFC7230】章节 5.5)。

Here, a "non-error response" is one with a 2xx (Successful) or 3xx (Redirection) status code. "Invalidate" means that the cache will either remove all stored responses related to the effective request URI or will mark these as "invalid" and in need of a mandatory validation before they can be sent in response to a subsequent request.

所述“非错误的响应”,指的是带有状态码为 2xx (Successful)3xx (Redirection) 的响应。所述“失效invalidate”,意味着缓存将会这样做:要么移除该有效请求 URI 相关的所有已存储的响应,要么将这些已存储的响应标记为“无效invalid”并且在它们可以用来响应给后续请求之前需要强制的验证mandatory validation

Note that this does not guarantee that all appropriate responses are invalidated. For example, a state-changing request might invalidate responses in the caches it travels through, but relevant responses still might be stored in other caches that it has not.

需要注意的是这样做并不保证所有合适的响应都会被失效。例如,一个会改变状态的请求可能会将它所途经的缓存中的响应置为失效,但存储在其他缓存中的相关响应仍然未被失效。

5. 头字段定义 / Header Field Definitions

This section defines the syntax and semantics of HTTP/1.1 header fields related to caching.

本章节定义了缓存相关的 HTTP/1.1 头字段的句法与语义。

5.1. Age

The "Age" header field conveys the sender's estimate of the amount of time since the response was generated or successfully validated at the origin server. Age values are calculated as specified in Section 4.2.3.

Age 头字段运载了发送端的估算时长,该估算时长是从该响应被源服务器生成generated成功验证successfully validated到现在所持续的时长。章节 4.2.3 指出了 Age 字段值的计算方法。

Age = delta-seconds

The Age field-value is a non-negative integer, representing time in seconds (see Section 1.2.1).

Age 的字段值是一个非负整数,以秒为单位来表示时间(章节 1.2.1)。

The presence of an Age header field implies that the response was not generated or validated by the origin server for this request. However, lack of an Age header field does not imply the origin was contacted, since the response might have been received from an HTTP/1.0 cache that does not implement Age.

Age 头字段的出现意味着这个响应并不是由源服务器生成的或验证的。但是,缺少 Age 头字段并不意味着缓存已与源服务器取得联系,因为这个响应也可能是接收自一个 HTTP/1.0 缓存,而 HTTP/1.0 缓存并没有实现 Age

5.2. Cache-Control

The "Cache-Control" header field is used to specify directives for caches along the request/response chain. Such cache directives are unidirectional in that the presence of a directive in a request does not imply that the same directive is to be given in the response.

Cache-Control 头字段用于指定请求/响应链路中所使用的缓存指令。这些缓存指令是意向的,即请求中出现一个指令并不意味着响应中将会出现同一个指令。

A cache MUST obey the requirements of the Cache-Control directives defined in this section. See Section 5.2.3 for information about how Cache-Control directives defined elsewhere are handled.

缓存 必须 遵守本章节所定义的 Cache-Control 指令的要求。关于如何处理在别处(非本规范)定义的 Cache-Control 指令,见章节 5.2.3

Note: Some HTTP/1.0 caches might not implement Cache-Control.

注意: 某些 HTTP/1.0 缓存可能没有实现 Cache-Control

A proxy, whether or not it implements a cache, MUST pass cache directives through in forwarded messages, regardless of their significance to that application, since the directives might be applicable to all recipients along the request/response chain. It is not possible to target a directive to a specific cache.

一个代理,无论它是否有实现了缓存功能,必须 在转发消息的同时放行缓存指令的转发,无论这些指令对那个应用程序是否有意义,这是因为这些指令可能会应用于请求/响应链路中的所有接收端。发送一个指令以某一个具体的缓存为目标是不可能的。

Cache directives are identified by a token, to be compared case-insensitively, and have an optional argument, that can use both token and quoted-string syntax. For the directives defined below that define arguments, recipients ought to accept both forms, even if one is documented to be preferred. For any directive not defined by this specification, a recipient MUST accept both forms.

缓存指令由一个 token 所标识,不区分大小写,它可以带有一个可选的实参argument,这个实参既可以使用 token 句法来表示,也可以使用 quoted-string 来表示。对于下文所定义的指令中有定义实参的,接收端应该能够同时接受这两种实参形式,即使其中一种形式是被注明为首选的。对于其他任何非本规范所定义的指令,接收端 必须 能够同时接受这两种实参形式。

Cache-Control   = 1#cache-directive

cache-directive = token [ "=" ( token / quoted-string ) ]

For the cache directives defined below, no argument is defined (nor allowed) unless stated otherwise.

对于下文所定义的指令中,除非另有说明,没有定义(也不允许有)实参。

5.2.1. 请求消息中的缓存控制指令 / Request Cache-Control Directives

5.2.1.1. max-age

Argument syntax:

实参句法:

delta-seconds (see Section 1.2.1)

The "max-age" request directive indicates that the client is unwilling to accept a response whose age is greater than the specified number of seconds. Unless the max-stale request directive is also present, the client is not willing to accept a stale response.

max-age 请求指令表明,客户端不愿意去接受这一种响应:其年龄大于指令所指定的秒数值。除非也出现了 max-stale 请求指令,否则客户端不愿意接受一个陈旧的响应stale response

译注:响应的年龄age,见章节 4.2.3

This directive uses the token form of the argument syntax: e.g., 'max-age=5' not 'max-age="5"'. A sender SHOULD NOT generate the quoted-string form.

本指令的实参使用的是 token 形式的句法,比如:max-age=5,而不是 max-age="5"。发送端 不应当 将本指令生成为 quoted-string 的形式。

5.2.1.2. max-stale

Argument syntax:

实参句法:

delta-seconds (see Section 1.2.1)

The "max-stale" request directive indicates that the client is willing to accept a response that has exceeded its freshness lifetime. If max-stale is assigned a value, then the client is willing to accept a response that has exceeded its freshness lifetime by no more than the specified number of seconds. If no value is assigned to max-stale, then the client is willing to accept a stale response of any age.

max-stale 请求指令表明,客户端愿意去接受这一种响应:已经超出了保鲜期的,即陈旧的响应stale response。如果 max-stale 已被赋值,那么,客户端愿意去接受这一种响应:已经超出了保鲜期的,但超出的时长不大于本指令所指定的秒数值。如果 max-stale 还未被赋值,那么,客户端愿意去接受 任意年龄 的陈旧响应。

译注:陈旧的响应stale response,见章节 4.2.4

This directive uses the token form of the argument syntax: e.g., 'max-stale=10' not 'max-stale="10"'. A sender SHOULD NOT generate the quoted-string form.

本指令的实参使用的是 token 形式的句法,比如:max-stale=10,而不是 max-stale="10"。发送端 不应当 将本指令生成为 quoted-string 的形式。

5.2.1.3. min-fresh

Argument syntax:

实参句法:

delta-seconds (see Section 1.2.1)

The "min-fresh" request directive indicates that the client is willing to accept a response whose freshness lifetime is no less than its current age plus the specified time in seconds. That is, the client wants a response that will still be fresh for at least the specified number of seconds.

min-fresh 请求指令表明,客户端愿意去接受这一种响应:它的保鲜期freshness lifetime不少于它的当前年龄age加上本指令所指定的秒数时间。也就是说,客户端想要这样的一种响应:至少在指定的秒数值之内仍然是新鲜的。

译注:保鲜期freshness lifetime是一个秒数值,而不是一个绝对时间点,其定义见章节 4.2

This directive uses the token form of the argument syntax: e.g., 'min-fresh=20' not 'min-fresh="20"'. A sender SHOULD NOT generate the quoted-string form.

本指令的实参使用的是 token 形式的句法,比如:max-fresh=20,而不是 max-fresh="20"。发送端 不应当 将本指令生成为 quoted-string 的形式。

5.2.1.4. no-cache

The "no-cache" request directive indicates that a cache MUST NOT use a stored response to satisfy the request without successful validation on the origin server.

no-cache 请求指令表明,缓存在没有经源服务器成功验证的情况下,禁止 使用一个已存储的响应来满足这个请求。

5.2.1.5. no-store

The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it. This directive applies to both private and shared caches. "MUST NOT store" in this context means that the cache MUST NOT intentionally store the information in non-volatile storage, and MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible after forwarding it.

no-store 请求指令表明,缓存 禁止 存储这次请求及其对应的任何响应的任何部分。本指令既适用于私有缓存private caches,也适用于共享缓存shared caches。这里“禁止存储”的意思是缓存 禁止非易失性存储器non-volatile storage中刻意存储信息,而且 必须 在转发这些信息以后,立刻、尽最大努力地去尝试从易失性存储器volatile storage中移除它们。

译注:私有缓存和共享缓存的描述,见章节 1

译注:上述“信息”指的是这次请求以及对应的所有响应的任何部分。

This directive is NOT a reliable or sufficient mechanism for ensuring privacy. In particular, malicious or compromised caches might not recognize or obey this directive, and communications networks might be vulnerable to eavesdropping.

本指令并不是一个可靠的或者充分的机制来保证私密性。特别是,恶意的或者折衷的缓存可能不服从obey或者无法识别recognize本指令,从而通信网络可能会遭到窃听。

Note that if a request containing this directive is satisfied from a cache, the no-store request directive does not apply to the already stored response.

需要注意的是,如果包含本指令的一个请求被一个缓存所满足,那么,no-store 请求指令并不适用于已经存储的响应。

译注:no-store 是告诉缓存,不要存储本次请求及其回应给这个请求的响应,它是不会影响到早已存储在缓存中的响应的。

5.2.1.6. no-transform

The "no-transform" request directive indicates that an intermediary (whether or not it implements a cache) MUST NOT transform the payload, as defined in Section 5.7.2 of [RFC7230].

no-transform 请求指令表明,中间人intermediary(无论是否有实现缓存) 禁止 转换有效载荷payload,正如【RFC7230】章节 5.7.2 所定义的。

5.2.1.7. only-if-cached

The "only-if-cached" request directive indicates that the client only wishes to obtain a stored response. If it receives this directive, a cache SHOULD either respond using a stored response that is consistent with the other constraints of the request, or respond with a 504 (Gateway Timeout) status code. If a group of caches is being operated as a unified system with good internal connectivity, a member cache MAY forward such a request within that group of caches.

only-if-cached 请求指令表明,客户端只希望获取一个已存储的响应。如果一个缓存接收到本指令,那么,它 应当 要么回应一个符合请求的其他约束的已存储的响应,要么回应一个 504 (Gateway Timeout) 状态码。如果一组缓存作为一个统一的系统来运作,它们之间具有良好的内部连通性,那么,组内的成员缓存 可以 在组内的缓存之间转发这种请求。

5.2.2. 响应消息中的缓存控制指令 / Response Cache-Control Directives

5.2.2.1. must-revalidate

The "must-revalidate" response directive indicates that once it has become stale, a cache MUST NOT use the response to satisfy subsequent requests without successful validation on the origin server.

must-revalidate 响应指令表明:一旦这个响应消息变得陈旧,那么,缓存 禁止 在没有经过源服务器成功验证的情况下,使用这个响应来满足后续的请求。

The must-revalidate directive is necessary to support reliable operation for certain protocol features. In all circumstances a cache MUST obey the must-revalidate directive; in particular, if a cache cannot reach the origin server for any reason, it MUST generate a 504 (Gateway Timeout) response.

为支持某些协议功能的可靠操作,must-revalidat 指令是很有必要的。在任何情况下,缓存 必须 服从 must-revalidate 指令。特别是如果一个缓存出于任何原因而不能访问源服务器的情况下,它 必须 生成一个 504 (Gateway Timeout) 响应。

The must-revalidate directive ought to be used by servers if and only if failure to validate a request on the representation could result in incorrect operation, such as a silently unexecuted financial transaction.

服务器应该使用 must-revalidate 指令,当且仅当在表示形式上验证一个请求失败时可能会导致不正确的操作,比如一个静默未执行的财务交易。

5.2.2.2. no-cache

Argument syntax:

实参句法:

#field-name

The "no-cache" response directive indicates that the response MUST NOT be used to satisfy a subsequent request without successful validation on the origin server. This allows an origin server to prevent a cache from using it to satisfy a request without contacting it, even by caches that have been configured to send stale responses.

no-cache 响应指令表明:这个响应在没有经过源服务器的成功验证的情况下,禁止 被用来满足后续的请求。这样使得源服务器可以阻止缓存在不联系源服务器的情况下使用这个响应来满足某个请求,即使这些缓存已被配置为可以发送陈旧响应。

If the no-cache response directive specifies one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching. However, any header fields in the response that have the field-name(s) listed MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent the re-use of certain header fields in a response, while still allowing caching of the rest of the response.

如果 no-cache 响应指令指定了一个或多个字段名field-names,那么,缓存 可以 使用这个响应来满足一个后续的请求,但会受到任何其他关于缓存方面的约束。然而,响应消息的 no-cache 指令中所列出的任何字段名 禁止 在没有经过源服务器成功验证的情况下,出现在回应给一个后续请求的响应中。这样使得源服务器可以阻止某些头字段在一个响应中被复用,但仍然允许缓存响应的剩余部分。

The field-names given are not limited to the set of header fields defined by this specification. Field names are case-insensitive.

这里所说的字段名field-names并不限于由本规范所定义的头字段集。字段名是不区分大小写的。

This directive uses the quoted-string form of the argument syntax. A sender SHOULD NOT generate the token form (even if quoting appears not to be needed for single-entry lists).

本指令的实参使用的是 quoted-string 形式的句法。发送端 不应当 将本指令生成为 token 的形式(即使在只有单一条目的列表中看起来并不需要引号)。

Note: Although it has been back-ported to many implementations, some HTTP/1.0 caches will not recognize or obey this directive. Also, no-cache response directives with field-names are often handled by caches as if an unqualified no-cache directive was received; i.e., the special handling for the qualified form is not widely implemented.

注意: 虽然本指令已被移植到许多实现上,但是,某些 HTTP/1.0 缓存将不会识别或者不会服从它。另外,带有字段名的 no-cache 响应指令常常被缓存当作未经限定的unqualified no-cache 来处理,也就是说,对于限定形式的特殊处理并没有得到广泛的实现。

5.2.2.3. no-store

The "no-store" response directive indicates that a cache MUST NOT store any part of either the immediate request or response. This directive applies to both private and shared caches. "MUST NOT store" in this context means that the cache MUST NOT intentionally store the information in non-volatile storage, and MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible after forwarding it.

no-store 响应指令表明,缓存 禁止 存储这个响应及其引起这个响应的请求的任何部分。本指令既适用于私有缓存,也适用于共享缓存。这里“禁止存储”的意思是缓存 禁止非易失性存储器non-volatile storage中刻意存储信息,而且 必须 在转发这些信息以后,立刻、尽最大努力地去尝试从易失性存储器volatile storage中移除它们。

This directive is NOT a reliable or sufficient mechanism for ensuring privacy. In particular, malicious or compromised caches might not recognize or obey this directive, and communications networks might be vulnerable to eavesdropping.

本指令并不是一个可靠的或者充分的机制来保证私密性。特别是,恶意的或者折衷的缓存可能不服从obey或者无法识别recognize本指令,从而通信网络可能会遭到窃听。

5.2.2.4. no-transform

The "no-transform" response directive indicates that an intermediary (regardless of whether it implements a cache) MUST NOT transform the payload, as defined in Section 5.7.2 of [RFC7230].

no-transform 响应指令表明,中间人(无论它是否有实现了缓存功能) 禁止 转换有效载荷,其定义见【RFC7230】章节 5.7.2

5.2.2.5. public

The "public" response directive indicates that any cache MAY store the response, even if the response would normally be non-cacheable or cacheable only within a private cache. (See Section 3.2 for additional details related to the use of public in response to a request containing Authorization, and Section 3 for details of how public affects responses that would normally not be stored, due to their status codes not being defined as cacheable by default; see Section 4.2.2.)

public 响应指令表明,任何缓存都 可以 存储这个响应,即使在正常情况下这个响应是不可缓存的或者仅可缓存于某个私有缓存中。(在回应给带有 Authorization 的请求的这种响应里使用 public 的更多详细信息,见章节 3.2;以及 public 如何影响正常情况下是不可存储的响应(由于它们的状态码没有定义为默认是可缓存的,见章节 4.2.2)的细节,见章节 3;)

5.2.2.6. private

Argument syntax:

实参句法:

#field-name

The "private" response directive indicates that the response message is intended for a single user and MUST NOT be stored by a shared cache. A private cache MAY store the response and reuse it for later requests, even if the response would normally be non-cacheable.

private 响应指令表明,这个响应消息是打算给某个单一用户使用的,并且 禁止 被共享缓存所存储。隐私缓存 可以 存储这个响应和在接下来的请求中复用这个响应,即使这个响应在正常情况下是不可缓存的。

If the private response directive specifies one or more field-names, this requirement is limited to the field-values associated with the listed response header fields. That is, a shared cache MUST NOT store the specified field-names(s), whereas it MAY store the remainder of the response message.

如果 private 响应指令指定了一个或多个字段名称,那么,这个要求仅限于所列出的响应头字段所关联的字段值。也就是说,共享缓存 禁止 存储 private 所指定的字段名,但它 可以 存储响应消息的剩余部分。

The field-names given are not limited to the set of header fields defined by this specification. Field names are case-insensitive.

这里所说的字段名field-names并不限于由本规范所定义的头字段集。字段名是不区分大小写的。

This directive uses the quoted-string form of the argument syntax. A sender SHOULD NOT generate the token form (even if quoting appears not to be needed for single-entry lists).

本指令的实参使用的是 quoted-string 形式的句法。发送端 不应当 将本指令生成为 token 的形式(即使在只有单一条目的列表中看起来并不需要引号)。

Note: This usage of the word "private" only controls where the response can be stored; it cannot ensure the privacy of the message content. Also, private response directives with field-names are often handled by caches as if an unqualified private directive was received; i.e., the special handling for the qualified form is not widely implemented.

注意: 这里所使用的术语“private”(私有)仅控制响应能够存储在哪个地方,它并不能保证消息内容的隐私性。另外,带有字段名称的 private 响应指令常常被缓存当作未经限定的unqualified private 来处理,也就是说,对于限定形式的特殊处理并没有得到广泛的实现。

5.2.2.7. proxy-revalidate

The "proxy-revalidate" response directive has the same meaning as the must-revalidate response directive, except that it does not apply to private caches.

proxy-revalidate 响应指令与 must-revalidate 响应指令具有同样的含义,除了它并不能适用于私有缓存以外。

5.2.2.8. max-age

Argument syntax:

实参句法:

delta-seconds (see Section 1.2.1)

The "max-age" response directive indicates that the response is to be considered stale after its age is greater than the specified number of seconds.

max-age 响应指令表明,在响应的年龄大于这个指令所指定的秒数以后,这个响应就被视为是陈旧的stale

This directive uses the token form of the argument syntax: e.g., 'max-age=5' not 'max-age="5"'. A sender SHOULD NOT generate the quoted-string form.

本指令的实参使用的是 token 形式的句法,比如:max-age=5,而不是 max-age="5"。发送端 不应当 将本指令生成为 quoted-string 的形式。

5.2.2.9. s-maxage

Argument syntax:

实参句法:

delta-seconds (see Section 1.2.1)

The "s-maxage" response directive indicates that, in shared caches, the maximum age specified by this directive overrides the maximum age specified by either the max-age directive or the Expires header field. The s-maxage directive also implies the semantics of the proxy-revalidate response directive.

s-maxage 响应指令表明,在共享缓存中,由本指令所指定的最大年龄值覆盖了 max-age 指令或者 Expires 头字段所指定的最大年龄值。s-maxage 指令还意味着 proxy-revalidate 响应指令的语义。

This directive uses the token form of the argument syntax: e.g., 's-maxage=10' not 's-maxage="10"'. A sender SHOULD NOT generate the quoted-string form.

本指令的实参使用的是 token 形式的句法,比如:s-maxage=10,而不是 s-maxage="10"。发送端 不应当 将本指令生成为 quoted-string 的形式。

5.2.3. 缓存控制扩展 / Cache Control Extensions

The Cache-Control header field can be extended through the use of one or more cache-extension tokens, each with an optional value. A cache MUST ignore unrecognized cache directives.

可以通过使用一个或多个缓存扩展标记cache-extension tokens来扩展 Cache-Control 头字段,每个缓存扩展都有一个可选的值。缓存 必须 忽略不能识别的缓存指令。

Informational extensions (those that do not require a change in cache behavior) can be added without changing the semantics of other directives.

信息性的扩展Informational extensions(指的是并不要求改变缓存行为的那种扩展)能够被添加而不会改变其他指令的语义。

Behavioral extensions are designed to work by acting as modifiers to the existing base of cache directives. Both the new directive and the old directive are supplied, such that applications that do not understand the new directive will default to the behavior specified by the old directive, and those that understand the new directive will recognize it as modifying the requirements associated with the old directive. In this way, extensions to the existing cache-control directives can be made without breaking deployed caches.

行为扩展Behavioral extensions是为在现有的缓存指令的基础上充当修饰符而设计的。既支持新指令,也支持旧指令,以便于不理解新指令的应用程序可以进行由旧指令所指定的默认行为,而理解新指令的应用程序则会将它认为是对旧指令的相关要求进行修改。这样就能够制定对现有的缓存控制指令的扩展而不会破坏已部署好的缓存。

For example, consider a hypothetical new response directive called "community" that acts as a modifier to the private directive: in addition to private caches, any cache that is shared only by members of the named community is allowed to cache the response. An origin server wishing to allow the UCI community to use an otherwise private response in their shared cache(s) could do so by including

例如,假设有一个新的响应指令称为 "community",充当 private 指令的修饰符:除了私有缓存以外,任何仅共享于 community 指令所指定的名称的团体的缓存也允许缓存这个响应。源服务器希望让 UCI 团体可以使用在它们的共享缓存中的另外一个私有响应来满足请求,可以在响应中包含以下内容:

Cache-Control: private, community="UCI"

A cache that recognizes such a community cache-extension could broaden its behavior in accordance with that extension. A cache that does not recognize the community cache-extension would ignore it and adhere to the private directive.

能够识别这个 community 缓存扩展的一类缓存,可以依照这个扩展的定义来拓宽它的行为。而不能识别这个 community 缓存扩展的一类缓存,可以忽略它而去遵守 private 指令。

5.3. Expires

The "Expires" header field gives the date/time after which the response is considered stale. See Section 4.2 for further discussion of the freshness model.

Expires 头字段所给出的日期/时间,意思是在这个时间点以后,响应会被视为是陈旧的。对于新鲜度模型的进一步讨论,见章节 4.2

The presence of an Expires field does not imply that the original resource will change or cease to exist at, before, or after that time.

Expires 头字段的出现并不意味着在那个时间点、之前、或者之后,原始资源将会出现变化或者不复存在。

The Expires value is an HTTP-date timestamp, as defined in Section 7.1.1.1 of [RFC7231].

Expires 的值是一个 HTTP-date 时间戳,其定义见【RFC7231】章节 7.1.1.1

Expires = HTTP-date

For example

例如:

Expires: Thu, 01 Dec 1994 16:00:00 GMT

A cache recipient MUST interpret invalid date formats, especially the value "0", as representing a time in the past (i.e., "already expired").

缓存接收端 必须 解释无效的日期格式,特别是值为 "0",代替过去的时间(也就是说,已经过期)。

If a response includes a Cache-Control field with the max-age directive (Section 5.2.2.8), a recipient MUST ignore the Expires field. Likewise, if a response includes the s-maxage directive (Section 5.2.2.9), a shared cache recipient MUST ignore the Expires field. In both these cases, the value in Expires is only intended for recipients that have not yet implemented the Cache-Control field.

如果响应包含有一个 Cache-Control 字段,这个字段带有一个 max-age 指令(章节 5.2.2.8),那么,接收端 必须 忽略 Expires 字段。同样,如果响应包含有一个 s-maxage 指令(章节 5.2.2.9),那么,共享缓存接收端 必须 忽略 Expires 字段。在上述两种情况中,Expires 里的值是仅为还未实现 Cache-Control 字段的那些接收端而设的。

An origin server without a clock MUST NOT generate an Expires field unless its value represents a fixed time in the past (always expired) or its value has been associated with the resource by a system or user with a reliable clock.

不具有时钟功能的源服务器 禁止 生成一个 Expires 字段,除非它的值代表着一个过去的固定时间(总是过期的)或者它的值是由某些具有可靠时钟功能的其他系统或用户关联到资源上的。

Historically, HTTP required the Expires field-value to be no more than a year in the future. While longer freshness lifetimes are no longer prohibited, extremely large values have been demonstrated to cause problems (e.g., clock overflows due to use of 32-bit integers for time values), and many caches will evict a response far sooner than that.

历史上,HTTP 要求 Expires 的字段值不能超过未来一年的时间。虽然现在已经不再禁止更长的保鲜期,但极端大的值已被证明会引发问题(比如,由于使用了 32 位整数作为时间值而导致的时钟溢出),而且许多缓存会将远早于响应的过期时间的那些响应逐出缓存。

5.4. Pragma

The "Pragma" header field allows backwards compatibility with HTTP/1.0 caches, so that clients can specify a "no-cache" request that they will understand (as Cache-Control was not defined until HTTP/1.1). When the Cache-Control header field is also present and understood in a request, Pragma is ignored.

Pragma 头字段使得可以与 HTTP/1.0 的缓存保持向后兼容,以便客户端能够指定一个它们能够理解的 "no-cache" 请求(因为直到 HTTP/1.1 Cache-Control 才被定义出来)。当请求中还出现了 Cache-Control 头字段且被接收端所理解,那么,Pragma 会被忽略。

In HTTP/1.0, Pragma was defined as an extensible field for implementation-specified directives for recipients. This specification deprecates such extensions to improve interoperability.

在 HTTP/1.0 中,Pragma 被定义为是一个可扩展的字段,它的含义依据接收端实现所指定。为提升互操作性,本规范废弃了这种扩展。

译注:也就是说,Pragma 是一个没有确定语义的字段,在不同的实现中可能有所不同。

Pragma           = 1#pragma-directive
pragma-directive = "no-cache" / extension-pragma
extension-pragma = token [ "=" ( token / quoted-string ) ]

When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).

当请求中没有出现 Cache-Control 头字段,那么,缓存 必须Pragmano-cache 指令的效果视同为与 "Cache-Control: no-cache" 一致(见章节 5.2.1)。

When sending a no-cache request, a client ought to include both the pragma and cache-control directives, unless Cache-Control: no-cache is purposefully omitted to target other Cache-Control response directives at HTTP/1.1 caches. For example:

当发送一个 no-cache 请求,客户端应该既包含 Pragma 也包含 Cache-Control 指令,除非有意忽略 Cache-Control: no-cache 而对 HTTP/1.1 缓存使用其他 Cache-Control 响应指令。例如:

GET / HTTP/1.1
Host: www.example.com
Cache-Control: max-age=30
Pragma: no-cache

will constrain HTTP/1.1 caches to serve a response no older than 30 seconds, while precluding implementations that do not understand Cache-Control from serving a cached response.

上面例子将会迫使 HTTP/1.1 缓存去供应一个年龄不超过 30 秒的响应,而阻止并不理解 Cache-Control 的实现去供应一个已缓存的响应。

Note: Because the meaning of "Pragma: no-cache" in responses is not specified, it does not provide a reliable replacement for "Cache-Control: no-cache" in them.

注意: 因为响应中 "Pragma: no-cache" 的含义并不是明确的,因此,它并不能可靠地替代 "Cache-Control: no-cache"。

5.5. Warning

The "Warning" header field is used to carry additional information about the status or transformation of a message that might not be reflected in the status code. This information is typically used to warn about possible incorrectness introduced by caching operations or transformations applied to the payload of the message.

当消息的状态或者转换可能并没有反映在状态码时,可以使用 Warning 头字段来运载消息的状态或者转换相关的额外信息。这些信息通常用于警告由缓存操作或应用到消息有效载荷上的转换而可能引起的错误。

Warnings can be used for other purposes, both cache-related and otherwise. The use of a warning, rather than an error status code, distinguishes these responses from true failures.

Warning 能够用于其他目的,可以是缓存相关的,也可以是其他方面。使用 Warning 而不是错误状态码,其区别是这些响应是否是真正的错误。

Warning header fields can in general be applied to any message, however some warn-codes are specific to caches and can only be applied to response messages.

Warning 头字段通常可以应用到任何消息中,然而,某些 warn-code (警告码)是专门用于缓存方面的,并且仅能应用于响应消息。

Warning       = 1#warning-value

warning-value = warn-code SP warn-agent SP warn-text
                                      [ SP warn-date ]

warn-code  = 3DIGIT
warn-agent = ( uri-host [ ":" port ] ) / pseudonym
                ; the name or pseudonym of the server adding
                ; the Warning header field, for use in debugging
                ; a single "-" is recommended when agent unknown
warn-text  = quoted-string
warn-date  = DQUOTE HTTP-date DQUOTE

Multiple warnings can be generated in a response (either by the origin server or by a cache), including multiple warnings with the same warn-code number that only differ in warn-text.

在一个响应中可以生成多个 Warning (要么由源服务器生成,要么由某个缓存生成),包括具有同一个 warn-code 的多个警告而只有在 warn-text 上有所区别。

A user agent that receives one or more Warning header fields SHOULD inform the user of as many of them as possible, in the order that they appear in the response. Senders that generate multiple Warning header fields are encouraged to order them with this user agent behavior in mind. A sender that generates new Warning header fields MUST append them after any existing Warning header fields.

当用户代理接收到一个或多个 Warning 头字段时,应当 尽可能将它们都告知给用户,按它们出现在响应中的顺序。发送端在生成多个 Warning 头字段时最好按照用户代理的行为习惯来对它们进行排序。发送端在生成新的 Warning 头字段的时候,必须 将它附加到任何已存在的 Warning 头字段之后。

Warnings are assigned three digit warn-codes. The first digit indicates whether the Warning is required to be deleted from a stored response after validation:

  • 1xx warn-codes describe the freshness or validation status of the response, and so they MUST be deleted by a cache after validation. They can only be generated by a cache when validating a cached entry, and MUST NOT be generated in any other situation.
  • 2xx warn-codes describe some aspect of the representation that is not rectified by a validation (for example, a lossy compression of the representation) and they MUST NOT be deleted by a cache after validation, unless a full response is sent, in which case they MUST be.

Warningwarn-code 是一个 3 位数字。第一位数字表明这个 Warning 是否必须在验证以后从已存储的响应中删除:

  • 1xxwarn-code 描述了响应的新鲜度或验证的状态,因此它们 必须 在验证以后被缓存所删除。它们仅可以在验证一个已缓存的条目的时候由缓存所生成,并且 禁止 在其他任何情况下生成它们。
  • 2xxwarn-code 描述了在验证之后不会被修复矫正的表示形式的某些方面(例如,表示形式的一个有损压缩),并且缓存在验证以后 禁止 删除它们,除非发送一个完整的响应(这时候就 必须 删除它们了)。

If a sender generates one or more 1xx warn-codes in a message to be sent to a recipient known to implement only HTTP/1.0, the sender MUST include in each corresponding warning-value a warn-date that matches the Date header field in the message. For example:

如果发送端在一个消息中生成了一个或多个 1xx 警告码,而它知道这个消息是发往一个只实现了 HTTP/1.0 的接收端的,那么,发送端 必须 在每一个对应的 warning-value 中包含一个与消息中的 Date 头字段相匹配的 warn-date,例如:

HTTP/1.1 200 OK
Date: Sat, 25 Aug 2012 23:34:45 GMT
Warning: 112 - "network down" "Sat, 25 Aug 2012 23:34:45 GMT"

Warnings have accompanying warn-text that describes the error, e.g., for logging. It is advisory only, and its content does not affect interpretation of the warn-code.

Warning 中附带的 warn-text 描述了错误,又如,为了日志记录。它仅供参考,其内容并不会影响到 warn-code 的解释。

If a recipient that uses, evaluates, or displays Warning header fields receives a warn-date that is different from the Date value in the same message, the recipient MUST exclude the warning-value containing that warn-date before storing, forwarding, or using the message. This allows recipients to exclude warning-values that were improperly retained after a cache validation. If all of the warning-values are excluded, the recipient MUST exclude the Warning header field as well.

如果某些 Warning 头字段中的 warn-date 不同于同一个消息中的 Date 字段值,那么,接收端在使用、求值、或者展示这些 Warning 头字段的时候,必须 在存储、转发、或者使用这个消息之前,排除掉所有包含那个 warn-datewarning-value。这样使得接收端可以排除掉那些在缓存验证以后不恰当保留下来的 warning-value。如果排除了所有的 warning-value,那么,接收端 必须 连同 Warning 头字段一起排除掉。

The following warn-codes are defined by this specification, each with a recommended warn-text in English, and a description of its meaning. The procedure for defining additional warn codes is described in Section 7.2.1.

本规范定义了下列 warn-code,每个都有一个推荐的英文 warn-text,以及一段描述它的含义的文字。定义额外的警告码的手续在章节 7.2.1 中有所描述。

5.5.1. Warning: 110 - "Response is Stale"

A cache SHOULD generate this whenever the sent response is stale.

每当缓存所发送的响应是陈旧的(即已过期)时候,缓存就 应当 生成这个警告码。

5.5.2. Warning: 111 - "Revalidation Failed"

A cache SHOULD generate this when sending a stale response because an attempt to validate the response failed, due to an inability to reach the server.

之所以发送一个陈旧的响应是因为由于缓存无法访问服务器而导致验证失败,这时候,缓存 应当 生成这个警告码。

5.5.3. Warning: 112 - "Disconnected Operation"

A cache SHOULD generate this if it is intentionally disconnected from the rest of the network for a period of time.

如果缓存有意断开网络连接一段时间,那么,它 应当 生成这个警告码。

5.5.4. Warning: 113 - "Heuristic Expiration"

A cache SHOULD generate this if it heuristically chose a freshness lifetime greater than 24 hours and the response's age is greater than 24 hours.

如果缓存采用启发式方法,将缓存的有效时间设定为 24 小时以上,并且响应的年龄已大于 24 小时,那么,缓存 应当 生成一个警告码。

5.5.5. Warning: 199 - "Miscellaneous Warning"

The warning text can include arbitrary information to be presented to a human user or logged. A system receiving this warning MUST NOT take any automated action, besides presenting the warning to the user.

这里的 warn-text (警告文本)可以包含任意信息来展示给人类用户或者用来记录日志。接收到这种警告的系统 禁止 执行任何自动化行为,除了将这个警告展示给用户以外。

5.5.6. Warning: 214 - "Transformation Applied"

This Warning code MUST be added by a proxy if it applies any transformation to the representation, such as changing the content-coding, media-type, or modifying the representation data, unless this Warning code already appears in the response.

这个警告码 必须 由代理所添加,如果代理为表示形式执行了任何转换,比如改变 content-coding、媒体类型、或者修改了表示形式的数据的话,除非这个警告码已经出现在响应中。

5.5.7. Warning: 299 - "Miscellaneous Persistent Warning"

The warning text can include arbitrary information to be presented to a human user or logged. A system receiving this warning MUST NOT take any automated action.

这里的 warn-text (警告文本)可以包含任意信息来展示给人类用户或者用来记录日志。接收到这种警告的系统 禁止 执行任何自动化行为。

6. 历史列表 / History Lists

User agents often have history mechanisms, such as "Back" buttons and history lists, that can be used to redisplay a representation retrieved earlier in a session.

用户代理通常具有历史机制,比如“返回”按钮和历史列表,能够用来重新展示在会话中之前所获取到的展示形式。

The freshness model (Section 4.2) does not necessarily apply to history mechanisms. That is, a history mechanism can display a previous representation even if it has expired.

新鲜度模型(章节 4.2)并不一定要应用到这种历史机制上。也就是说,历史机制能够展示一个之前的表示形式,即使它已经过期了。

This does not prohibit the history mechanism from telling the user that a view might be stale or from honoring cache directives (e.g., Cache-Control: no-store).

这并没有阻止历史机制去告诉用户某个视图可能是陈旧的,也没有阻止它去履行缓存指令(比如,Cache-Control: no-store)。

7. IANA 注意事项 / IANA Considerations

7.1. 缓存指令登记表 / Cache Directive Registry

The "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" defines the namespace for the cache directives. It has been created and is now maintained at http://www.iana.org/assignments/http-cache-directives.

《HTTP 缓存指令登记表》定义了缓存指令的命名空间,这份登记表已经创建,目前维护在 http://www.iana.org/assignments/http-cache-directives

7.1.1. 手续 / Procedure

A registration MUST include the following fields:

  • Cache Directive Name
  • Pointer to specification text

一个登记条目 必须 包括以下字段:

  • 缓存指令名称
  • 指向到规范文本的引用

Values to be added to this namespace require IETF Review (see [RFC5226], Section 4.1).

添加到 HTTP 状态码命名空间的值要求由 IETF 复审(见【RFC5226】章节 4.1)。

7.1.2. 新的缓存控制指令的注意事项 / Considerations for New Cache Control Directives

New extension directives ought to consider defining:

  • What it means for a directive to be specified multiple times,
  • When the directive does not take an argument, what it means when an argument is present,
  • When the directive requires an argument, what it means when it is missing,
  • Whether the directive is specific to requests, responses, or able to be used in either.

新的扩展指令应该考虑定义:

  • 指令被指定多次的时候是什么含义,
  • 如果指令没有定义实参,当指令出现实参时是什么含义,
  • 如果指令要求带有实参,当指令没带有实参时是什么含义,
  • 指令是否专门用于请求消息、响应消息,还是能用于两者。

See also Section 5.2.3.

章节 5.2.3

7.1.3. 登记 / Registrations

The registry has been populated with the registrations below:

登记表已填充以下条目:

Cache Directive Reference
max-age Section 5.2.1.1, Section 5.2.2.8
max-stale Section 5.2.1.2
min-fresh Section 5.2.1.3
must-revalidate Section 5.2.2.1
no-cache Section 5.2.1.4, Section 5.2.2.2
no-store Section 5.2.1.5, Section 5.2.2.3
no-transform Section 5.2.1.6, Section 5.2.2.4
only-if-cached Section 5.2.1.7
private Section 5.2.2.6
proxy-revalidate Section 5.2.2.7
public Section 5.2.2.5
s-maxage Section 5.2.2.9
stale-if-error [RFC5861], Section 4
stale-while-revalidate [RFC5861], Section 3

7.2. 警告码登记表 / Warn Code Registry

The "Hypertext Transfer Protocol (HTTP) Warn Codes" registry defines the namespace for warn codes. It has been created and is now maintained at http://www.iana.org/assignments/http-warn-codes.

《HTTP 警告码登记表》定义了警告码的命名空间,这份登记表已经创建,目前维护在 http://www.iana.org/assignments/http-warn-codes

7.2.1. 手续 / Procedure

A registration MUST include the following fields:

  • Warn Code (3 digits)
  • Short Description
  • Pointer to specification text

一个登记条目 必须 包括以下字段:

  • 警告码(3 位数字)
  • 简短的描述
  • 指向到规范文本的引用

Values to be added to this namespace require IETF Review (see [RFC5226], Section 4.1).

添加到 HTTP 本命名空间的值要求由 IETF 复审(见【RFC5226】章节 4.1)。

7.2.2. 登记 / Registrations

The registry has been populated with the registrations below:

登记表已填充以下条目:

Warn Code Short Description Reference
110 Response is Stale Section 5.5.1
111 Revalidation Failed Section 5.5.2
112 Disconnected Operation Section 5.5.3
113 Heuristic Expiration Section 5.5.4
199 Miscellaneous Warning Section 5.5.5
214 Transformation Applied Section 5.5.6
299 Miscellaneous Persistent Warning Section 5.5.7

7.3. 头字段登记 / Header Field Registration

HTTP header fields are registered within the "Message Headers" registry maintained at http://www.iana.org/assignments/message-headers/.

HTTP 头字段登记有 《消息头登记表》中,目前维护在 http://www.iana.org/assignments/message-headers/

This document defines the following HTTP header fields, so the "Permanent Message Header Field Names" registry has been updated accordingly (see [BCP90]).

本文档定义了以下 HTTP 头字段,因此,《永久消息头字段名称登记表》已经相应地更新过了(见【BCP90】)。

Header Field Name Protocol Status Reference
Age http standard Section 5.1
Cache-Control http standard Section 5.2
Expires http standard Section 5.3
Pragma http standard Section 5.4
Warning http standard Section 5.5

The change controller is: "IETF (iesg@ietf.org) - Internet Engineering Task Force".

主管以上条目的变更的是 "IETF (iesg@ietf.org) - Internet Engineering Task Force"。

8. 安全注意事项 / Security Considerations

This section is meant to inform developers, information providers, and users of known security concerns specific to HTTP caching. More general security considerations are addressed in HTTP messaging [RFC7230] and semantics [RFC7231].

本章节是为了告诉开发者、信息提供商、以及用户,HTTP 缓存相关的安全注意事项。《消息句法和路由》【RFC7230】以及《语义和内容》【RFC7231】有更广泛的安全注意事项。

Caches expose additional potential vulnerabilities, since the contents of the cache represent an attractive target for malicious exploitation. Because cache contents persist after an HTTP request is complete, an attack on the cache can reveal information long after a user believes that the information has been removed from the network. Therefore, cache contents need to be protected as sensitive information.

缓存暴露了额外的可能的安全弱点,因为缓存的内容代表着一种有吸引力的恶意利用的目标。由于缓存的内容在 HTTP 请求完成以后仍然保留,因此,针对缓存的攻击能够长久暴露用户相信已经从网络中移除掉的那些信息。所以,缓存内容需要作为敏感信息来进行保护。

In particular, various attacks might be amplified by being stored in a shared cache; such "cache poisoning" attacks use the cache to distribute a malicious payload to many clients, and are especially effective when an attacker can use implementation flaws, elevated privileges, or other techniques to insert such a response into a cache. One common attack vector for cache poisoning is to exploit differences in message parsing on proxies and in user agents; see Section 3.3.3 of [RFC7230] for the relevant requirements.

特别是,如果信息被存储到共享缓存的话,这种攻击可能会扩展为更多样的攻击,比如“缓存中毒cache poisoning”攻击使用缓存来将某种恶意的有效载荷分发到许多客户端上,当攻击者能够使用实现缺陷、提升权限、或其他技术来植入这种恶意响应到缓存上的时候,这种攻击会特别有效。一个常见的缓存攻击的途径是利用在代理和在用户代理上消息解析message parsing上的差异来达到,见章节【RFC7230】3.3.3 的相关要求。

Likewise, implementation flaws (as well as misunderstanding of cache operation) might lead to caching of sensitive information (e.g., authentication credentials) that is thought to be private, exposing it to unauthorized parties.

同样,实现缺陷(和其他缓存操作上的误解)可能导致缓存了理应是私有的敏感信息(比如,身份凭证),暴露到未经认证的群体当中。

Furthermore, the very use of a cache can bring about privacy concerns. For example, if two users share a cache, and the first one browses to a site, the second may be able to detect that the other has been to that site, because the resources from it load more quickly, thanks to the cache.

而且,缓存的方便带来了隐私方面的问题。例如,如果两个用户共享一个缓存,第一个用户浏览了一个网站,那么第二个用户可能能够检测到对方访问过那个网站,因为加载这个网站的资源很快,多亏了缓存。

Note that the Set-Cookie response header field [RFC6265] does not inhibit caching; a cacheable response with a Set-Cookie header field can be (and often is) used to satisfy subsequent requests to caches. Servers who wish to control caching of these responses are encouraged to emit appropriate Cache-Control response header fields.

需要注意的是,Set-Cookie 响应头字段【RFC6265】并没有禁止缓存操作,一个带有 Set-Cookie 头字段的可缓存的响应可以用来(并且通常用来)满足后续对缓存的请求。如果服务器希望控制对这些响应的缓存操作,最好发送合适的 Cache-Control 响应头字段。

9. 鸣谢 / Acknowledgments

See Section 10 of [RFC7230].

【RFC7230】章节 10

10. 参考资料 / References

10.1. 规范性参考资料 / Normative References

[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, January 2008.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, June 2014.
[RFC7231]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, June 2014.
[RFC7232]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests”, RFC 7232, June 2014.
[RFC7233]
Fielding, R., Ed., Lafon, Y., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Range Requests”, RFC 7233, June 2014.
[RFC7235]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Authentication”, RFC 7235, June 2014.

10.2. 信息性参考资料 / Informative References

[BCP90]
Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004.
[RFC2616]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, “Hypertext Transfer Protocol – HTTP/1.1”, RFC 2616, June 1999.
[RFC5226]
Narten, T. and H. Alvestrand, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 5226, May 2008.
[RFC5861]
Nottingham, M., “HTTP Cache-Control Extensions for Stale Content”, RFC 5861, April 2010.
[RFC5905]
Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, “Network Time Protocol Version 4: Protocol and Algorithms Specification”, RFC 5905, June 2010.
[RFC6265]
Barth, A., “HTTP State Management Mechanism”, RFC 6265, April 2011.

附录 A:相对 RFC 2616 的变化 / Appendix A. Changes from RFC 2616

The specification has been substantially rewritten for clarity.

为了明确,本规范已经大幅度重写了。

The conditions under which an authenticated response can be cached have been clarified. (Section 3.2)

明确了在什么条件下,能够缓存一个已认证的响应。(章节 3.2

New status codes can now define that caches are allowed to use heuristic freshness with them. Caches are now allowed to calculate heuristic freshness for URIs with query components. (Section 4.2.2)

新的状态码现在可以将缓存定义为允许对它们使用启发式新鲜度。现在允许缓存去计算带有 query 组件的 URI 的启发式新鲜度。(章节 4.2.2

The algorithm for calculating age is now less conservative. Caches are now required to handle dates with time zones as if they're invalid, because it's not possible to accurately guess. (Section 4.2.3)

现在计算年龄的算法不会那么保守了。现在要求缓存将带有时区的日期当作无效日期来处理,因为无法精确地猜测。(章节 4.2.3

The Content-Location response header field is no longer used to determine the appropriate response to use when validating. (Section 4.3)

Content-Location 响应头字段已不再使用来决定在验证的时候哪一个响应才是恰当的。(章节 4.3

The algorithm for selecting a cached negotiated response to use has been clarified in several ways. In particular, it now explicitly allows header-specific canonicalization when processing selecting header fields. (Section 4.1)

明确了关于选择一个缓存协商响应来使用的算法为多种方式。特别是,当处理选择头字段的时候,它现在显式允许头部指定的标准。(章节 4.1

Requirements regarding denial-of-service attack avoidance when performing invalidation have been clarified. (Section 4.4)

明确了当执行缓存失效操作performing invalidation时如何避免拒绝服务攻击的相关要求。(章节 4.4

Cache invalidation only occurs when a successful response is received. (Section 4.4)

缓存失效仅会发生于接收到一个成功响应的时候。(章节 4.4

Cache directives are explicitly defined to be case-insensitive. Handling of multiple instances of cache directives when only one is expected is now defined. (Section 5.2)

显式定义缓存指令为不区别大小写。现在已定义了当仅期望一个缓存指令时,如何处理出现多个缓存指令实例的情况。(章节 5.2

The "no-store" request directive doesn't apply to responses; i.e., a cache can satisfy a request with no-store on it and does not invalidate it. (Section 5.2.1.5)

no-store 请求指令并不适用于响应消息,也就是说,缓存可以满足一个带有 no-store 指令的请求而不用将其设为失效。(章节 5.2.1.5

The qualified forms of the private and no-cache cache directives are noted to not be widely implemented; for example, "private=foo" is interpreted by many caches as simply "private". Additionally, the meaning of the qualified form of no-cache has been clarified. (Section 5.2.2)

目前已知 privateno-cache 缓存指令的限定形式qualified forms并未广泛实现,例如,许多缓存只会将 "private=foo" 简单解释为 "private"。另外,明确了 no-cache 的限定形式的含义。(章节 5.2.2

The "no-cache" response directive's meaning has been clarified. (Section 5.2.2.2)

明确了 no-cache 响应指令的含义。(章节 5.2.2.2

The one-year limit on Expires header field values has been removed; instead, the reasoning for using a sensible value is given. (Section 5.3)

移除了 Expires 头字段值的一年限制,另外还给出了使用一个合理值的原因。(章节 5.3

The Pragma header field is now only defined for backwards compatibility; future pragmas are deprecated. (Section 5.4)

现在,Pragma 头字段仅为向后兼容而定义,废弃了以后(定义)的杂注。(章节 5.4

Some requirements regarding production and processing of the Warning header fields have been relaxed, as it is not widely implemented. Furthermore, the Warning header field no longer uses RFC 2047 encoding, nor does it allow multiple languages, as these aspects were not implemented. (Section 5.5)

放宽了 Warning 头字段的产生以及处理的某些相关要求,因为它并未得到广泛实现。而且,Warning 头字段不再使用 RFC 2047 编码,也不允许多语言,因为这些方面都没有得到实现。(章节 5.5

This specification introduces the Cache Directive and Warn Code Registries, and defines considerations for new cache directives. (Section 7.1 and Section 7.2)

本规范引入了缓存指令以及警告码登记表,并定义了新缓存指令时的注意事项。(章节 7.1章节 7.2

附录 B:引进的 ABNF / Appendix B. Imported ABNF

The following core rules are included by reference, as defined in Appendix B.1 of [RFC5234]: ALPHA (letters), CR (carriage return), CRLF (CR LF), CTL (controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG (hexadecimal 0-9/A-F/a-f), LF (line feed), OCTET (any 8-bit sequence of data), SP (space), and VCHAR (any visible US-ASCII character).

本规范引用了以下定义在【RFC5234】附录 B.1 中的核心规则:ALPHA (字母)、CR (回车符)、CRLF (回车换行符)、CTL (控制字符)、DIGIT (十进制数字 0-9)、DQUOTE (双引号)、HEXDIG (十六进制数字 0-9/A-F/a-f)、HTAB (水平制表符)、LF (换行符)、OCTET (八位组字节)、SP (空白)以及 VCHAR (【USASCII】可见字符)。

The rules below are defined in [RFC7230]:

下列规则定义在【RFC7230】:

OWS           = <OWS, see [RFC7230], Section 3.2.3>
field-name    = <field-name, see [RFC7230], Section 3.2>
quoted-string = <quoted-string, see [RFC7230], Section 3.2.6>
token         = <token, see [RFC7230], Section 3.2.6>

port          = <port, see [RFC7230], Section 2.7>
pseudonym     = <pseudonym, see [RFC7230], Section 5.7.1> 
uri-host      = <uri-host, see [RFC7230], Section 2.7>

The rules below are defined in other parts:

下列规则定义在 HTTP/1.1 规范的其他部分中:

HTTP-date     = <HTTP-date, see [RFC7231], Section 7.1.1.1>

附录 C:ABNF 集合 / Appendix C. Collected ABNF

In the collected ABNF below, list rules are expanded as per Section 1.2 of [RFC7230].

下列 ABNF 规则集合中,列表规则是在【RFC7230】章节 1.2 所扩充的。

Age = delta-seconds

Cache-Control = *( "," OWS ) cache-directive *( OWS "," [ OWS
 cache-directive ] )

Expires = HTTP-date

HTTP-date = <HTTP-date, see [RFC7231], Section 7.1.1.1>

OWS = <OWS, see [RFC7230], Section 3.2.3>

Pragma = *( "," OWS ) pragma-directive *( OWS "," [ OWS
 pragma-directive ] )

Warning = *( "," OWS ) warning-value *( OWS "," [ OWS warning-value ]
 )

cache-directive = token [ "=" ( token / quoted-string ) ]

delta-seconds = 1*DIGIT

extension-pragma = token [ "=" ( token / quoted-string ) ]

field-name = <field-name, see [RFC7230], Section 3.2>

port = <port, see [RFC7230], Section 2.7>
pragma-directive = "no-cache" / extension-pragma
pseudonym = <pseudonym, see [RFC7230], Section 5.7.1>

quoted-string = <quoted-string, see [RFC7230], Section 3.2.6>

token = <token, see [RFC7230], Section 3.2.6>

uri-host = <uri-host, see [RFC7230], Section 2.7>

warn-agent = ( uri-host [ ":" port ] ) / pseudonym
warn-code = 3DIGIT
warn-date = DQUOTE HTTP-date DQUOTE
warn-text = quoted-string
warning-value = warn-code SP warn-agent SP warn-text [ SP warn-date
 ]

索引 / Index

  • 1
    • 110 (warn-code) 4.2.4, 5.5.1, 7.2.2
    • 111 (warn-code) 5.5.2, 7.2.2
    • 112 (warn-code) 4.2.4, 5.5.3, 7.2.2
    • 113 (warn-code) 4.2.2, 5.5.4, 7.2.2
    • 199 (warn-code) 5.5.5, 7.2.2
  • 2
    • 214 (warn-code) 5.5.6, 7.2.2
    • 299 (warn-code) 5.5.7, 7.2.2
  • A
    • age 4.2
    • Age header field 4, 4.2.3, 5.1, 7.3
  • B
    • BCP90 7.3, 10.2
  • C
    • cache 1
    • cache entry 2
    • cache key 2, 2
    • Cache-Control header field 3, 5.2, 7.3, A
  • D
    • Disconnected Operation (warn-text) 4.2.4, 5.5.3, 7.2.2
  • E
    • Expires header field 3, 4.2, 4.2.1, 5.3, 7.3, A
    • explicit expiration time 4.2
  • F
    • fresh 4.2
    • freshness lifetime 4.2
  • G
    • Grammar
      • Age 5.1
      • Cache-Control 5.2
      • cache-directive 5.2
      • delta-seconds 1.2.1
      • Expires 5.3
      • extension-pragma 5.4
      • Pragma 5.4
      • pragma-directive 5.4
      • warn-agent 5.5
      • warn-code 5.5
      • warn-date 5.5
      • warn-text 5.5
      • Warning 5.5
      • warning-value 5.5
  • H
    • Heuristic Expiration (warn-text) 4.2.2, 5.5.4, 7.2.2
    • heuristic expiration time 4.2
  • M
    • max-age (cache directive) 5.2.1.1, 5.2.2.8
    • max-stale (cache directive) 5.2.1.2
    • min-fresh (cache directive) 5.2.1.3
    • Miscellaneous Persistent Warning (warn-text) 5.5.7, 7.2.2
    • Miscellaneous Warning (warn-text) 5.5.5, 7.2.2
    • must-revalidate (cache directive) 5.2.2.1
  • N
    • no-cache (cache directive) 5.2.1.4, 5.2.2.2
    • no-store (cache directive) 5.2.1.5, 5.2.2.3
    • no-transform (cache directive) 5.2.1.6, 5.2.2.4
  • O
    • only-if-cached (cache directive) 5.2.1.7
  • P
    • Pragma header field 4, 5.4, 7.3, A
    • private (cache directive) 5.2.2.6
    • private cache 1
    • proxy-revalidate (cache directive) 5.2.2.7
    • public (cache directive) 5.2.2.5
  • R
    • Response is Stale (warn-text) 4.2.4, 5.5.1, 7.2.2
    • Revalidation Failed (warn-text) 5.5.2, 7.2.2
    • RFC2119 1.1, 10.1
    • RFC2616 4.2.2, 10.2
      • Section 13.9 4.2.2
    • RFC5226 7.1.1, 7.2.1, 10.2
      • Section 4.1 7.1.1, 7.2.1
    • RFC5234 1.2, 10.1, B
      • Appendix B.1 B
    • RFC5861 7.1.3, 7.1.3, 10.2
      • Section 3 7.1.3
      • Section 4 7.1.3
    • RFC5905 4.2.3, 10.2
    • RFC6265 8, 10.2
    • RFC7230 1.1, 1.2, 3.1, 4, 4.1, 4.4, 4.4, 4.4, 5.2.1.6, 5.2.2.4, 8, 8, 9, 10.1, B, B, B, B, B, B, B, B, C
      • Section 1.2 C
      • Section 2.5 1.1
      • Section 2.7 B, B
      • Section 3.2 4.1, B
      • Section 3.2.3 B
      • Section 3.2.6 B, B
      • Section 3.3.3 8
      • Section 5.5 4, 4.4, 4.4, 4.4
      • Section 5.7.1 B
      • Section 5.7.2 5.2.1.6, 5.2.2.4
      • Section 7 1.2
      • Section 10 9
    • RFC7231 2, 2, 4, 4.1, 4.2.2, 4.2.3, 4.4, 5.3, 8, 10.1, B
      • Section 4.2.1 4, 4.4
      • Section 4.3.1 2
      • Section 6.1 4.2.2
      • Section 7.1.1.1 5.3, B
      • Section 7.1.1.2 4.2.3
      • Section 7.1.4 4.1
    • RFC7232 4.2.2, 4.3, 4.3.1, 4.3.1, 4.3.2, 4.3.2, 4.3.2, 4.3.4, 10.1
      • Section 2.1 4.3.4
      • Section 2.2 4.2.2, 4.3.1
      • Section 2.3 4.3.1
      • Section 3.2 4.3.2
      • Section 3.3 4.3.2
      • Section 6 4.3.2
    • RFC7233 3.1, 3.3, 3.3, 4.3.2, 4.3.2, 10.1
      • Section 3.2 4.3.2
      • Section 4.3 3.3
    • RFC7235 3, 3.2, 10.1
      • Section 4.2 3, 3.2
  • S
    • s-maxage (cache directive) 5.2.2.9
    • shared cache 1
    • stale 4.2
    • strong validator 4.3.4
  • T
    • Transformation Applied (warn-text) 5.5.6, 7.2.2
  • V
    • validator 4.3.1
  • W
    • Warning header field 3.3, 4.3.4, 4.3.5, 5.5, 7.3, A

Authors' Addresses

Roy T. Fielding (editor)
Adobe Systems Incorporated
345 Park Ave
San Jose, CA 95110
USA
Email: fielding@gbiv.com
URI: http://roy.gbiv.com/
Mark Nottingham (editor)
Akamai
Email: mnot@mnot.net
URI: http://www.mnot.net/
Julian F. Reschke (editor)
greenbytes GmbH
Hafenweg 16
Muenster, NW 48155
Germany
Email: julian.reschke@greenbytes.de
URI: http://greenbytes.de/tech/webdav/
阿多(译者)