draft-ietf-httpbis-cache-05.txt   draft-ietf-httpbis-cache-06.txt 
HTTP Working Group R. Fielding, Ed. HTTP Working Group R. Fielding, Ed.
Internet-Draft Adobe Internet-Draft Adobe
Obsoletes: 7234 (if approved) M. Nottingham, Ed. Obsoletes: 7234 (if approved) M. Nottingham, Ed.
Intended status: Standards Track Fastly Intended status: Standards Track Fastly
Expires: January 9, 2020 J. Reschke, Ed. Expires: May 7, 2020 J. Reschke, Ed.
greenbytes greenbytes
July 8, 2019 November 4, 2019
HTTP Caching HTTP Caching
draft-ietf-httpbis-cache-05 draft-ietf-httpbis-cache-06
Abstract Abstract
The Hypertext Transfer Protocol (HTTP) is a stateless application- The Hypertext Transfer Protocol (HTTP) is a stateless application-
level protocol for distributed, collaborative, hypertext information level protocol for distributed, collaborative, hypertext information
systems. This document defines HTTP caches and the associated header systems. This document defines HTTP caches and the associated header
fields that control cache behavior or indicate cacheable response fields that control cache behavior or indicate cacheable response
messages. messages.
This document obsoletes RFC 7234. This document obsoletes RFC 7234.
skipping to change at page 1, line 36 skipping to change at page 1, line 36
This note is to be removed before publishing as an RFC. This note is to be removed before publishing as an RFC.
Discussion of this draft takes place on the HTTP working group Discussion of this draft takes place on the HTTP working group
mailing list (ietf-http-wg@w3.org), which is archived at mailing list (ietf-http-wg@w3.org), which is archived at
<https://lists.w3.org/Archives/Public/ietf-http-wg/>. <https://lists.w3.org/Archives/Public/ietf-http-wg/>.
Working Group information can be found at <https://httpwg.org/>; Working Group information can be found at <https://httpwg.org/>;
source code and issues list for this draft can be found at source code and issues list for this draft can be found at
<https://github.com/httpwg/http-core>. <https://github.com/httpwg/http-core>.
The changes in this draft are summarized in Appendix C.6. The changes in this draft are summarized in Appendix C.7.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 9, 2020. This Internet-Draft will expire on May 7, 2020.
Copyright Notice Copyright Notice
Copyright (c) 2019 IETF Trust and the persons identified as the Copyright (c) 2019 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 41 skipping to change at page 2, line 41
outside the IETF Standards Process, and derivative works of it may outside the IETF Standards Process, and derivative works of it may
not be created outside the IETF Standards Process, except to format not be created outside the IETF Standards Process, except to format
it for publication as an RFC or to translate it into languages other it for publication as an RFC or to translate it into languages other
than English. than English.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Requirements Notation . . . . . . . . . . . . . . . . . . 5 1.1. Requirements Notation . . . . . . . . . . . . . . . . . . 5
1.2. Syntax Notation . . . . . . . . . . . . . . . . . . . . . 5 1.2. Syntax Notation . . . . . . . . . . . . . . . . . . . . . 5
1.3. Delta Seconds . . . . . . . . . . . . . . . . . . . . . . 5 1.3. Delta Seconds . . . . . . . . . . . . . . . . . . . . . . 6
2. Overview of Cache Operation . . . . . . . . . . . . . . . . . 6 2. Overview of Cache Operation . . . . . . . . . . . . . . . . . 6
3. Storing Responses in Caches . . . . . . . . . . . . . . . . . 7 3. Storing Responses in Caches . . . . . . . . . . . . . . . . . 7
3.1. Storing Incomplete Responses . . . . . . . . . . . . . . 8 3.1. Storing Incomplete Responses . . . . . . . . . . . . . . 8
3.2. Storing Responses to Authenticated Requests . . . . . . . 8 3.2. Storing Responses to Authenticated Requests . . . . . . . 9
3.3. Combining Partial Content . . . . . . . . . . . . . . . . 9 3.3. Combining Partial Content . . . . . . . . . . . . . . . . 9
4. Constructing Responses from Caches . . . . . . . . . . . . . 9 4. Constructing Responses from Caches . . . . . . . . . . . . . 9
4.1. Calculating Secondary Keys with Vary . . . . . . . . . . 10 4.1. Calculating Cache Keys with Vary . . . . . . . . . . . . 10
4.2. Freshness . . . . . . . . . . . . . . . . . . . . . . . . 11 4.2. Freshness . . . . . . . . . . . . . . . . . . . . . . . . 12
4.2.1. Calculating Freshness Lifetime . . . . . . . . . . . 13 4.2.1. Calculating Freshness Lifetime . . . . . . . . . . . 13
4.2.2. Calculating Heuristic Freshness . . . . . . . . . . . 13 4.2.2. Calculating Heuristic Freshness . . . . . . . . . . . 14
4.2.3. Calculating Age . . . . . . . . . . . . . . . . . . . 14 4.2.3. Calculating Age . . . . . . . . . . . . . . . . . . . 14
4.2.4. Serving Stale Responses . . . . . . . . . . . . . . . 15 4.2.4. Serving Stale Responses . . . . . . . . . . . . . . . 16
4.3. Validation . . . . . . . . . . . . . . . . . . . . . . . 16 4.3. Validation . . . . . . . . . . . . . . . . . . . . . . . 16
4.3.1. Sending a Validation Request . . . . . . . . . . . . 16 4.3.1. Sending a Validation Request . . . . . . . . . . . . 16
4.3.2. Handling a Received Validation Request . . . . . . . 17 4.3.2. Handling a Received Validation Request . . . . . . . 17
4.3.3. Handling a Validation Response . . . . . . . . . . . 18 4.3.3. Handling a Validation Response . . . . . . . . . . . 19
4.3.4. Freshening Stored Responses upon Validation . . . . . 18 4.3.4. Freshening Stored Responses upon Validation . . . . . 19
4.3.5. Freshening Responses with HEAD . . . . . . . . . . . 19 4.3.5. Freshening Responses with HEAD . . . . . . . . . . . 20
4.4. Invalidation . . . . . . . . . . . . . . . . . . . . . . 20 4.4. Invalidation . . . . . . . . . . . . . . . . . . . . . . 20
5. Header Field Definitions . . . . . . . . . . . . . . . . . . 20 5. Header Field Definitions . . . . . . . . . . . . . . . . . . 21
5.1. Age . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5.1. Age . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5.2. Cache-Control . . . . . . . . . . . . . . . . . . . . . . 21 5.2. Cache-Control . . . . . . . . . . . . . . . . . . . . . . 22
5.2.1. Request Cache-Control Directives . . . . . . . . . . 22 5.2.1. Request Cache-Control Directives . . . . . . . . . . 23
5.2.1.1. max-age . . . . . . . . . . . . . . . . . . . . . 22 5.2.1.1. max-age . . . . . . . . . . . . . . . . . . . . . 23
5.2.1.2. max-stale . . . . . . . . . . . . . . . . . . . . 23 5.2.1.2. max-stale . . . . . . . . . . . . . . . . . . . . 23
5.2.1.3. min-fresh . . . . . . . . . . . . . . . . . . . . 23 5.2.1.3. min-fresh . . . . . . . . . . . . . . . . . . . . 24
5.2.1.4. no-cache . . . . . . . . . . . . . . . . . . . . 23 5.2.1.4. no-cache . . . . . . . . . . . . . . . . . . . . 24
5.2.1.5. no-store . . . . . . . . . . . . . . . . . . . . 24 5.2.1.5. no-store . . . . . . . . . . . . . . . . . . . . 24
5.2.1.6. no-transform . . . . . . . . . . . . . . . . . . 24 5.2.1.6. no-transform . . . . . . . . . . . . . . . . . . 25
5.2.1.7. only-if-cached . . . . . . . . . . . . . . . . . 24 5.2.1.7. only-if-cached . . . . . . . . . . . . . . . . . 25
5.2.2. Response Cache-Control Directives . . . . . . . . . . 24 5.2.2. Response Cache-Control Directives . . . . . . . . . . 25
5.2.2.1. must-revalidate . . . . . . . . . . . . . . . . . 24 5.2.2.1. must-revalidate . . . . . . . . . . . . . . . . . 25
5.2.2.2. no-cache . . . . . . . . . . . . . . . . . . . . 25 5.2.2.2. no-cache . . . . . . . . . . . . . . . . . . . . 26
5.2.2.3. no-store . . . . . . . . . . . . . . . . . . . . 26 5.2.2.3. no-store . . . . . . . . . . . . . . . . . . . . 26
5.2.2.4. no-transform . . . . . . . . . . . . . . . . . . 26 5.2.2.4. no-transform . . . . . . . . . . . . . . . . . . 27
5.2.2.5. public . . . . . . . . . . . . . . . . . . . . . 26 5.2.2.5. public . . . . . . . . . . . . . . . . . . . . . 27
5.2.2.6. private . . . . . . . . . . . . . . . . . . . . . 26 5.2.2.6. private . . . . . . . . . . . . . . . . . . . . . 27
5.2.2.7. proxy-revalidate . . . . . . . . . . . . . . . . 27 5.2.2.7. proxy-revalidate . . . . . . . . . . . . . . . . 28
5.2.2.8. max-age . . . . . . . . . . . . . . . . . . . . . 27 5.2.2.8. max-age . . . . . . . . . . . . . . . . . . . . . 28
5.2.2.9. s-maxage . . . . . . . . . . . . . . . . . . . . 27 5.2.2.9. s-maxage . . . . . . . . . . . . . . . . . . . . 28
5.2.3. Cache Control Extensions . . . . . . . . . . . . . . 28 5.2.3. Cache Control Extensions . . . . . . . . . . . . . . 29
5.2.4. Cache Directive Registry . . . . . . . . . . . . . . 29 5.2.4. Cache Directive Registry . . . . . . . . . . . . . . 30
5.3. Expires . . . . . . . . . . . . . . . . . . . . . . . . . 29 5.3. Expires . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.4. Pragma . . . . . . . . . . . . . . . . . . . . . . . . . 30 5.4. Pragma . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.5. Warning . . . . . . . . . . . . . . . . . . . . . . . . . 30 5.5. Warning . . . . . . . . . . . . . . . . . . . . . . . . . 31
6. Relationship to Applications . . . . . . . . . . . . . . . . 30 6. Relationship to Applications . . . . . . . . . . . . . . . . 31
7. Security Considerations . . . . . . . . . . . . . . . . . . . 31 7. Security Considerations . . . . . . . . . . . . . . . . . . . 32
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 32 7.1. Cache Poisoning . . . . . . . . . . . . . . . . . . . . . 32
8.1. Header Field Registration . . . . . . . . . . . . . . . . 32 7.2. Timing Attacks . . . . . . . . . . . . . . . . . . . . . 32
8.2. Cache Directive Registration . . . . . . . . . . . . . . 32 7.3. Caching of Sensitive Information . . . . . . . . . . . . 33
8.3. Warn Code Registry . . . . . . . . . . . . . . . . . . . 32 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.1. Header Field Registration . . . . . . . . . . . . . . . . 33
9.1. Normative References . . . . . . . . . . . . . . . . . . 32 8.2. Cache Directive Registration . . . . . . . . . . . . . . 33
9.2. Informative References . . . . . . . . . . . . . . . . . 33 8.3. Warn Code Registry . . . . . . . . . . . . . . . . . . . 33
Appendix A. Collected ABNF . . . . . . . . . . . . . . . . . . . 35 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 33
Appendix B. Changes from RFC 7234 . . . . . . . . . . . . . . . 35 9.1. Normative References . . . . . . . . . . . . . . . . . . 33
Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 35 9.2. Informative References . . . . . . . . . . . . . . . . . 34
C.1. Between RFC7234 and draft 00 . . . . . . . . . . . . . . 35 Appendix A. Collected ABNF . . . . . . . . . . . . . . . . . . . 36
C.2. Since draft-ietf-httpbis-cache-00 . . . . . . . . . . . . 36 Appendix B. Changes from RFC 7234 . . . . . . . . . . . . . . . 36
C.3. Since draft-ietf-httpbis-cache-01 . . . . . . . . . . . . 36 Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 36
C.4. Since draft-ietf-httpbis-cache-02 . . . . . . . . . . . . 36 C.1. Between RFC7234 and draft 00 . . . . . . . . . . . . . . 36
C.5. Since draft-ietf-httpbis-cache-03 . . . . . . . . . . . . 37 C.2. Since draft-ietf-httpbis-cache-00 . . . . . . . . . . . . 37
C.6. Since draft-ietf-httpbis-cache-04 . . . . . . . . . . . . 37 C.3. Since draft-ietf-httpbis-cache-01 . . . . . . . . . . . . 37
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 C.4. Since draft-ietf-httpbis-cache-02 . . . . . . . . . . . . 37
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 39 C.5. Since draft-ietf-httpbis-cache-03 . . . . . . . . . . . . 38
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 39 C.6. Since draft-ietf-httpbis-cache-04 . . . . . . . . . . . . 38
C.7. Since draft-ietf-httpbis-cache-05 . . . . . . . . . . . . 38
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 40
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 40
1. Introduction 1. Introduction
The Hypertext Transfer Protocol (HTTP) is a stateless application- The Hypertext Transfer Protocol (HTTP) is a stateless application-
level request/response protocol that uses extensible semantics and level request/response protocol that uses extensible semantics and
self-descriptive messages for flexible interaction with network-based self-descriptive messages for flexible interaction with network-based
hypertext information systems. HTTP is defined by a series of hypertext information systems. HTTP is defined by a series of
documents that collectively form the HTTP/1.1 specification: documents that collectively form the HTTP/1.1 specification:
o "HTTP Semantics" [Semantics] o "HTTP Semantics" [Semantics]
skipping to change at page 5, line 26 skipping to change at page 5, line 30
Conformance criteria and considerations regarding error handling are Conformance criteria and considerations regarding error handling are
defined in Section 3 of [Semantics]. defined in Section 3 of [Semantics].
1.2. Syntax Notation 1.2. Syntax Notation
This specification uses the Augmented Backus-Naur Form (ABNF) This specification uses the Augmented Backus-Naur Form (ABNF)
notation of [RFC5234], extended with the notation for case- notation of [RFC5234], extended with the notation for case-
sensitivity in strings defined in [RFC7405]. sensitivity in strings defined in [RFC7405].
It also uses a list extension, defined in Section 11 of [Semantics], It also uses a list extension, defined in Section 12 of [Semantics],
that allows for compact definition of comma-separated lists using a that allows for compact definition of comma-separated lists using a
'#' operator (similar to how the '*' operator indicates repetition). '#' operator (similar to how the '*' operator indicates repetition).
Appendix A shows the collected grammar with all list operators Appendix A shows the collected grammar with all list operators
expanded to standard ABNF notation. expanded to standard ABNF notation.
The following core rules are included by reference, as defined in The following core rules are included by reference, as defined in
[RFC5234], Appendix B.1: ALPHA (letters), CR (carriage return), CRLF [RFC5234], Appendix B.1: ALPHA (letters), CR (carriage return), CRLF
(CR LF), CTL (controls), DIGIT (decimal 0-9), DQUOTE (double quote), (CR LF), CTL (controls), DIGIT (decimal 0-9), DQUOTE (double quote),
HEXDIG (hexadecimal 0-9/A-F/a-f), HTAB (horizontal tab), LF (line HEXDIG (hexadecimal 0-9/A-F/a-f), HTAB (horizontal tab), LF (line
feed), OCTET (any 8-bit sequence of data), SP (space), and VCHAR (any feed), OCTET (any 8-bit sequence of data), SP (space), and VCHAR (any
visible [USASCII] character). visible [USASCII] character).
The rules below are defined in [Semantics]: The rules below are defined in [Semantics]:
HTTP-date = <HTTP-date, see [Semantics], Section 10.1.1.1> HTTP-date = <HTTP-date, see [Semantics], Section 10.1.1.1>
OWS = <OWS, see [Semantics], Section 4.3> OWS = <OWS, see [Semantics], Section 11.1>
field-name = <field-name, see [Semantics], Section 4.2> field-name = <field-name, see [Semantics], Section 4.1>
quoted-string = <quoted-string, see [Semantics], Section 4.2.3> quoted-string = <quoted-string, see [Semantics], Section 4.2.3.2>
token = <token, see [Semantics], Section 4.2.3> token = <token, see [Semantics], Section 4.2.3.1>
1.3. Delta Seconds 1.3. Delta Seconds
The delta-seconds rule specifies a non-negative integer, representing The delta-seconds rule specifies a non-negative integer, representing
time in seconds. time in seconds.
delta-seconds = 1*DIGIT delta-seconds = 1*DIGIT
A recipient parsing a delta-seconds value and converting it to binary 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- form ought to use an arithmetic type of at least 31 bits of non-
skipping to change at page 6, line 36 skipping to change at page 6, line 41
Proper cache operation preserves the semantics of HTTP transfers Proper cache operation preserves the semantics of HTTP transfers
([Semantics]) while reducing the transfer of information already held ([Semantics]) while reducing the transfer of information already held
in the cache. Although caching is an entirely OPTIONAL feature of in the cache. Although caching is an entirely OPTIONAL feature of
HTTP, it can be assumed that reusing a cached response is desirable HTTP, it can be assumed that reusing a cached response is desirable
and that such reuse is the default behavior when no requirement or and that such reuse is the default behavior when no requirement or
local configuration prevents it. Therefore, HTTP cache requirements local configuration prevents it. Therefore, HTTP cache requirements
are focused on preventing a cache from either storing a non-reusable are focused on preventing a cache from either storing a non-reusable
response or reusing a stored response inappropriately, rather than response or reusing a stored response inappropriately, rather than
mandating that caches always store and reuse particular responses. mandating that caches always store and reuse particular responses.
Each cache entry consists of a cache key and one or more HTTP The base cache key consists of the request method and target URI used
responses corresponding to prior requests that used the same key. to retrieve the stored response; the method determines under which
The most common form of cache entry is a successful result of a circumstances that response can be used to satisfy a request.
retrieval request: i.e., a 200 (OK) response to a GET request, which However, many HTTP caches in common use today only cache GET
contains a representation of the resource identified by the request responses, and therefore only use the URI as the cache key,
target (Section 7.3.1 of [Semantics]). However, it is also possible forwarding other methods.
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.
The primary cache key consists of the request method and target URI. If a request target is subject to content negotiation, the cache
However, since HTTP caches in common use today are typically limited might store multiple responses for it. Caches differentiate these
to caching responses to GET, many caches simply decline other methods responses by incorporating values of the original request's selecting
and use only the URI as the primary cache key. header fields into the cache key as well, as per Section 4.1.
If a request target is subject to content negotiation, its cache Furthermore, caches might incorporate additional material into the
entry might consist of multiple stored responses, each differentiated cache key. For example, user agent caches might include the
by a secondary key for the values of the original request's selecting referring site's identity, thereby "double keying" the cache to avoid
header fields (Section 4.1). some privacy risks (see Section 7.2).
Most commonly, caches store the 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 7.3.1 of [Semantics]). However, it is also possible to
store 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.
A cache is disconnected when it cannot contact the origin server or A cache is disconnected when it cannot contact the origin server or
otherwise find a forward path for a given request. A disconnected otherwise find a forward path for a given request. A disconnected
cache can serve stale responses in some circumstances cache can serve stale responses in some circumstances
(Section 4.2.4). (Section 4.2.4).
3. Storing Responses in Caches 3. Storing Responses in Caches
A cache MUST NOT store a response to any request, unless: A cache MUST NOT store a response to any request, unless:
o The request method is understood by the cache and defined as being o The request method is understood by the cache, and
cacheable, and
o the response status code is final (see Section 9.3 of o the response status code is final (see Section 9.3 of
[Messaging]), and [Messaging]), and
o the response status code is understood by the cache, and o the response status code is understood by the cache, and
o the "no-store" cache directive (see Section 5.2) does not appear o the "no-store" cache directive (see Section 5.2) does not appear
in the response, and in the response, and
o the "private" response directive (see Section 5.2.2.6) does not o the "private" response directive (see Section 5.2.2.6) does not
skipping to change at page 7, line 42 skipping to change at page 8, line 4
o the Authorization header field (see Section 8.5.3 of [Semantics]) o the Authorization header field (see Section 8.5.3 of [Semantics])
does not appear in the request, if the cache is shared, unless the does not appear in the request, if the cache is shared, unless the
response explicitly allows it (see Section 3.2), and response explicitly allows it (see Section 3.2), and
o the response either: o the response either:
* contains an Expires header field (see Section 5.3), or * 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 max-age response directive (see Section 5.2.2.8), or
* contains a s-maxage response directive (see Section 5.2.2.9) * contains a s-maxage response directive (see Section 5.2.2.9)
and the cache is shared, or and the cache is shared, or
* contains a Cache Control Extension (see Section 5.2.3) that * contains a Cache Control Extension (see Section 5.2.3) that
allows it to be cached, or allows it to be cached, or
* has a status code that is defined as cacheable by default (see * has a status code that is defined as heuristically cacheable
Section 4.2.2), or (see Section 4.2.2), or
* contains a public response directive (see Section 5.2.2.5). * contains a public response directive (see Section 5.2.2.5).
Note that any of the requirements listed above can be overridden by a Note that any of the requirements listed above can be overridden by a
cache-control extension; see Section 5.2.3. cache-control extension; see Section 5.2.3.
In this context, a cache has "understood" a request method or a In this context, a cache has "understood" a request method or a
response status code if it recognizes it and implements all specified response status code if it recognizes it and implements all specified
caching-related behavior. caching-related behavior.
Note that, in normal operation, some caches will not store a response Note that, in normal operation, some caches will not store a response
that has neither a cache validator nor an explicit expiration time, that has neither a cache validator nor an explicit expiration time,
as such responses are not usually useful to store. However, caches as such responses are not usually useful to store. However, caches
are not prohibited from storing such responses. are not prohibited from storing such responses.
3.1. Storing Incomplete Responses 3.1. Storing Incomplete Responses
A response message is considered complete when all of the octets A response message is considered complete when all of the octets
indicated by the message framing ([Messaging]) are received prior to indicated by its framing are available. Note that, when no explicit
the connection being closed. If the request method is GET, the framing is provided, a response message that is ended by the
response status code is 200 (OK), and the entire response header connection's close is considered complete even though it might be
section has been received, a cache MAY store an incomplete response indistinguishable from an incomplete response (see [Messaging],
message body if the cache entry is recorded as incomplete. Likewise, Section 6.3). A cache SHOULD consider a close-terminated response
a 206 (Partial Content) response MAY be stored as if it were an incomplete if the connection termination is detected to be an error.
incomplete 200 (OK) cache entry. However, a cache MUST NOT store A server that wishes to avoid premature termination resulting in an
incomplete or partial-content responses if it does not support the incorrect cached response SHOULD send the response with explicit
Range and Content-Range header fields or if it does not understand framing.
the range units used in those fields.
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 stored response is
recorded as incomplete. Likewise, a 206 (Partial Content) response
MAY be stored as if it were an incomplete 200 (OK) response.
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.
A cache MAY complete a stored incomplete response by making a A cache MAY complete a stored incomplete response by making a
subsequent range request (Section 8.3 of [Semantics]) and combining subsequent range request (Section 8.3 of [Semantics]) and combining
the successful response with the stored entry, as defined in the successful response with the stored response, as defined in
Section 3.3. A cache MUST NOT use an incomplete response to answer 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 requests unless the response has been made complete or the request is
partial and specifies a range that is wholly within the incomplete partial and specifies a range that is wholly within the incomplete
response. A cache MUST NOT send a partial response to a client response. A cache MUST NOT send a partial response to a client
without explicitly marking it as such using the 206 (Partial Content) without explicitly marking it as such using the 206 (Partial Content)
status code. status code.
3.2. Storing Responses to Authenticated Requests 3.2. Storing Responses to Authenticated Requests
A shared cache MUST NOT use a cached response to a request with an A shared cache MUST NOT use a cached response to a request with an
skipping to change at page 10, line 29 skipping to change at page 10, line 44
responses; see Section 4.4. responses; see Section 4.4.
When more than one suitable response is stored, a cache MUST use the When more than one suitable response is stored, a cache MUST use the
most recent one (as determined by the Date header field). It can most recent one (as determined by the Date header field). It can
also forward the request with "Cache-Control: max-age=0" or "Cache- also forward the request with "Cache-Control: max-age=0" or "Cache-
Control: no-cache" to disambiguate which response to use. Control: no-cache" to disambiguate which response to use.
A cache that does not have a clock available MUST NOT use stored A cache that does not have a clock available MUST NOT use stored
responses without revalidating them upon every use. responses without revalidating them upon every use.
4.1. Calculating Secondary Keys with Vary 4.1. Calculating Cache Keys with Vary
When a cache receives a request that can be satisfied by a stored When a cache receives a request that can be satisfied by a stored
response that has a Vary header field (Section 10.1.4 of response that has a Vary header field (Section 10.1.4 of
[Semantics]), it MUST NOT use that response unless all of the [Semantics]), it MUST NOT use that response unless all of the
selecting header fields nominated by the Vary header field match in selecting header fields nominated by the Vary header field match in
both the original request (i.e., that associated with the stored both the original request (i.e., that associated with the stored
response), and the presented request. response), and the presented request.
The selecting header fields from two requests are defined to match if 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 and only if those in the first request can be transformed to those in
skipping to change at page 11, line 22 skipping to change at page 11, line 41
the selected response. the selected response.
If multiple selected responses are available (potentially including If multiple selected responses are available (potentially including
responses without a Vary header field), the cache will need to choose 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 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), doing so (e.g., qvalues on Accept and similar request header fields),
that mechanism MAY be used to select preferred responses; of the that mechanism MAY be used to select preferred responses; of the
remainder, the most recent response (as determined by the Date header remainder, the most recent response (as determined by the Date header
field) is used, as per Section 4. field) is used, as per Section 4.
Note that in practice, some resources might send the Vary header
field on responses inconsistently. When a cache has multiple
responses for a given target URI, and one or more omits the Vary
header field, it SHOULD use the most recent non-empty value available
to select an appropriate response for the request.
If no selected response is available, the cache cannot satisfy the If no selected response is available, the cache cannot satisfy the
presented request. Typically, it is forwarded to the origin server presented request. Typically, it is forwarded to the origin server
in a (possibly conditional; see Section 4.3) request. in a (possibly conditional; see Section 4.3) request.
4.2. Freshness 4.2. Freshness
A fresh response is one whose age has not yet exceeded its freshness A fresh response is one whose age has not yet exceeded its freshness
lifetime. Conversely, a stale response is one where it has. lifetime. Conversely, a stale response is one where it has.
A response's freshness lifetime is the length of time between its A response's freshness lifetime is the length of time between its
skipping to change at page 13, line 46 skipping to change at page 14, line 20
a cache MAY assign a heuristic expiration time when an explicit time a cache MAY assign a heuristic expiration time when an explicit time
is not specified, employing algorithms that use other header field is not specified, employing algorithms that use other header field
values (such as the Last-Modified time) to estimate a plausible values (such as the Last-Modified time) to estimate a plausible
expiration time. This specification does not provide specific expiration time. This specification does not provide specific
algorithms, but does impose worst-case constraints on their results. algorithms, but does impose worst-case constraints on their results.
A cache MUST NOT use heuristics to determine freshness when an A cache MUST NOT use heuristics to determine freshness when an
explicit expiration time is present in the stored response. Because explicit expiration time is present in the stored response. Because
of the requirements in Section 3, this means that, effectively, of the requirements in Section 3, this means that, effectively,
heuristics can only be used on responses without explicit freshness heuristics can only be used on responses without explicit freshness
whose status codes are defined as cacheable by default (see whose status codes are defined as "heuristically cacheable" (e.g.,
Section 9.1 of [Semantics]), and those responses without explicit see Section 9.1 of [Semantics]), and those responses without explicit
freshness that have been marked as explicitly cacheable (e.g., with a freshness that have been marked as explicitly cacheable (e.g., with a
"public" response directive). "public" response directive).
Note that in previous specifications heuristically cacheable response
status codes were called "cacheable by default."
If the response has a Last-Modified header field (Section 10.2.2 of If the response has a Last-Modified header field (Section 10.2.2 of
[Semantics]), caches are encouraged to use a heuristic expiration [Semantics]), caches are encouraged to use a heuristic expiration
value that is no more than some fraction of the interval since that value that is no more than some fraction of the interval since that
time. A typical setting of this fraction might be 10%. time. A typical setting of this fraction might be 10%.
Note: Section 13.9 of [RFC2616] prohibited caches from calculating Note: Section 13.9 of [RFC2616] prohibited caches from calculating
heuristic freshness for URIs with query components (i.e., those heuristic freshness for URIs with query components (i.e., those
containing '?'). In practice, this has not been widely containing '?'). In practice, this has not been widely
implemented. Therefore, origin servers are encouraged to send implemented. Therefore, origin servers are encouraged to send
explicit directives (e.g., Cache-Control: no-cache) if they wish explicit directives (e.g., Cache-Control: no-cache) if they wish
skipping to change at page 16, line 23 skipping to change at page 16, line 48
or to replace the stored response(s) with a new response. This or to replace the stored response(s) with a new response. This
process is known as "validating" or "revalidating" the stored process is known as "validating" or "revalidating" the stored
response. response.
4.3.1. Sending a Validation Request 4.3.1. Sending a Validation Request
When generating a conditional request for validation, a cache starts When generating a conditional request for validation, a cache starts
with either a request it is attempting to satisfy, or -- if it is with either a request it is attempting to satisfy, or -- if it is
initiating the request independently -- it synthesises a request initiating the request independently -- it synthesises a request
using a stored response by copying the method, request-target, and using a stored response by copying the method, request-target, and
request header fields used for identifying the secondary cache key request header fields identified by the Vary header field
Section 4.1. Section 4.1.
It then updates that request with one or more precondition header It then updates that request with one or more precondition header
fields. These contain validator metadata sourced from stored fields. These contain validator metadata sourced from stored
response(s) that have the same cache key (both primary and secondary, response(s) that have the same cache key.
as applicable).
The precondition header fields are then compared by recipients to The precondition header fields are then compared by recipients to
determine whether any stored response is equivalent to a current determine whether any stored response is equivalent to a current
representation of the resource. representation of the resource.
One such validator is the timestamp given in a Last-Modified header One such validator is the timestamp given in a Last-Modified header
field (Section 10.2.2 of [Semantics]), which can be used in an If- field (Section 10.2.2 of [Semantics]), which can be used in an If-
Modified-Since header field for response validation, or in an If- Modified-Since header field for response validation, or in an If-
Unmodified-Since or If-Range header field for representation Unmodified-Since or If-Range header field for representation
selection (i.e., the client is referring specifically to a previously selection (i.e., the client is referring specifically to a previously
skipping to change at page 26, line 39 skipping to change at page 27, line 24
payload, as defined in Section 5.5.2 of [Semantics]. payload, as defined in Section 5.5.2 of [Semantics].
5.2.2.5. public 5.2.2.5. public
The "public" response directive indicates that any cache MAY store The "public" response directive indicates that any cache MAY store
the response, even if the response would normally be non-cacheable or the response, even if the response would normally be non-cacheable or
cacheable only within a private cache. (See Section 3.2 for cacheable only within a private cache. (See Section 3.2 for
additional details related to the use of public in response to a additional details related to the use of public in response to a
request containing Authorization, and Section 3 for details of how request containing Authorization, and Section 3 for details of how
public affects responses that would normally not be stored, due to public affects responses that would normally not be stored, due to
their status codes not being defined as cacheable by default; see their status codes not being defined as heuristically cacheable; see
Section 4.2.2.) Section 4.2.2.)
5.2.2.6. private 5.2.2.6. private
Argument syntax: Argument syntax:
#field-name #field-name
The "private" response directive indicates that the response message The "private" response directive indicates that the response message
is intended for a single user and MUST NOT be stored by a shared is intended for a single user and MUST NOT be stored by a shared
skipping to change at page 31, line 35 skipping to change at page 32, line 25
[Messaging] and semantics [Semantics]. [Messaging] and semantics [Semantics].
Caches expose additional potential vulnerabilities, since the Caches expose additional potential vulnerabilities, since the
contents of the cache represent an attractive target for malicious contents of the cache represent an attractive target for malicious
exploitation. Because cache contents persist after an HTTP request exploitation. Because cache contents persist after an HTTP request
is complete, an attack on the cache can reveal information long after is complete, an attack on the cache can reveal information long after
a user believes that the information has been removed from the a user believes that the information has been removed from the
network. Therefore, cache contents need to be protected as sensitive network. Therefore, cache contents need to be protected as sensitive
information. information.
In particular, various attacks might be amplified by being stored in 7.1. Cache Poisoning
a shared cache; such "cache poisoning" attacks use the cache to
distribute a malicious payload to many clients, and are especially Various attacks might be amplified by being stored in a shared cache.
effective when an attacker can use implementation flaws, elevated Such "cache poisoning" attacks use the cache to distribute a
privileges, or other techniques to insert such a response into a malicious payload to many clients, and are especially effective when
cache. One common attack vector for cache poisoning is to exploit 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 differences in message parsing on proxies and in user agents; see
Section 6.3 of [Messaging] for the relevant requirements. Section 6.3 of [Messaging] for the relevant requirements regarding
HTTP/1.1.
Likewise, implementation flaws (as well as misunderstanding of cache 7.2. Timing Attacks
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 Because one of the primary uses of a cache is to optimise
concerns. For example, if two users share a cache, and the first one performance, its use can "leak" information about what resources have
browses to a site, the second may be able to detect that the other been previously requested.
has been to that site, because the resources from it load more
quickly, thanks to the cache. For example, if a user visits a site and their browser caches some of
its responses, and then navigates to a second site, that site can
attempt to load responses that it knows exists on the first site. If
they load very quickly, it can be assumed that the user has visited
that site, or even a specific page on it.
Such "timing attacks" can be mitigated by adding more information to
the cache key, such as the identity of the referring site (to prevent
the attack described above). This is sometimes called "double
keying."
7.3. Caching of Sensitive Information
Implementation and deployment 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.
Note that the Set-Cookie response header field [RFC6265] does not Note that the Set-Cookie response header field [RFC6265] does not
inhibit caching; a cacheable response with a Set-Cookie header field inhibit caching; a cacheable response with a Set-Cookie header field
can be (and often is) used to satisfy subsequent requests to caches. can be (and often is) used to satisfy subsequent requests to caches.
Servers who wish to control caching of these responses are encouraged Servers who wish to control caching of these responses are encouraged
to emit appropriate Cache-Control response header fields. to emit appropriate Cache-Control response header fields.
8. IANA Considerations 8. IANA Considerations
The change controller for the following registrations is: "IETF The change controller for the following registrations is: "IETF
skipping to change at page 32, line 43 skipping to change at page 33, line 50
Please add a note to the "Hypertext Transfer Protocol (HTTP) Warn Please add a note to the "Hypertext Transfer Protocol (HTTP) Warn
Codes" registry at <https://www.iana.org/assignments/http-warn-codes> Codes" registry at <https://www.iana.org/assignments/http-warn-codes>
to the effect that Warning is obsoleted. to the effect that Warning is obsoleted.
9. References 9. References
9.1. Normative References 9.1. Normative References
[Messaging] [Messaging]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP/1.1 Messaging", draft-ietf-httpbis-messaging-05 Ed., "HTTP/1.1 Messaging", draft-ietf-httpbis-messaging-06
(work in progress), July 2019. (work in progress), November 2019.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005, RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/info/rfc3986>. <https://www.rfc-editor.org/info/rfc3986>.
skipping to change at page 33, line 21 skipping to change at page 34, line 26
Specifications: ABNF", STD 68, RFC 5234, Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008, DOI 10.17487/RFC5234, January 2008,
<https://www.rfc-editor.org/info/rfc5234>. <https://www.rfc-editor.org/info/rfc5234>.
[RFC7405] Kyzivat, P., "Case-Sensitive String Support in ABNF", [RFC7405] Kyzivat, P., "Case-Sensitive String Support in ABNF",
RFC 7405, DOI 10.17487/RFC7405, December 2014, RFC 7405, DOI 10.17487/RFC7405, December 2014,
<https://www.rfc-editor.org/info/rfc7405>. <https://www.rfc-editor.org/info/rfc7405>.
[Semantics] [Semantics]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Semantics", draft-ietf-httpbis-semantics-05 Ed., "HTTP Semantics", draft-ietf-httpbis-semantics-06
(work in progress), July 2019. (work in progress), November 2019.
[USASCII] American National Standards Institute, "Coded Character [USASCII] American National Standards Institute, "Coded Character
Set -- 7-bit American Standard Code for Information Set -- 7-bit American Standard Code for Information
Interchange", ANSI X3.4, 1986. Interchange", ANSI X3.4, 1986.
9.2. Informative References 9.2. Informative References
[RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
Transfer Protocol -- HTTP/1.1", RFC 2616, Transfer Protocol -- HTTP/1.1", RFC 2616,
skipping to change at page 35, line 8 skipping to change at page 36, line 8
<https://www.rfc-editor.org/info/rfc7234>. <https://www.rfc-editor.org/info/rfc7234>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26, Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017, RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>. <https://www.rfc-editor.org/info/rfc8126>.
Appendix A. Collected ABNF Appendix A. Collected ABNF
In the collected ABNF below, list rules are expanded as per In the collected ABNF below, list rules are expanded as per
Section 11 of [Semantics]. Section 12 of [Semantics].
Age = delta-seconds Age = delta-seconds
Cache-Control = [ cache-directive ] *( OWS "," OWS [ cache-directive Cache-Control = [ cache-directive ] *( OWS "," OWS [ cache-directive
] ) ] )
Expires = HTTP-date Expires = HTTP-date
HTTP-date = <HTTP-date, see [Semantics], Section 10.1.1.1> HTTP-date = <HTTP-date, see [Semantics], Section 10.1.1.1>
skipping to change at page 37, line 33 skipping to change at page 38, line 33
o In Section 3.2 and Section 5.2.2, note effect of some directives o In Section 3.2 and Section 5.2.2, note effect of some directives
on authenticated requests (<https://github.com/httpwg/http-core/ on authenticated requests (<https://github.com/httpwg/http-core/
issues/161>) issues/161>)
C.6. Since draft-ietf-httpbis-cache-04 C.6. Since draft-ietf-httpbis-cache-04
o In Section 5.2, remove the registrations for stale-if-error and o In Section 5.2, remove the registrations for stale-if-error and
stale-while-revalidate which happened in RFC 7234 stale-while-revalidate which happened in RFC 7234
(<https://github.com/httpwg/http-core/issues/207>) (<https://github.com/httpwg/http-core/issues/207>)
C.7. Since draft-ietf-httpbis-cache-05
o In Section 3.1, clarify how weakly framed content is considered
for purposes of completeness (<https://github.com/httpwg/http-
core/issues/25>)
o Througout, describe Vary and cache key operations more clearly
(<https://github.com/httpwg/http-core/issues/28>)
o In Section 3, remove concept of "cacheable methods" in favor of
prose (<https://github.com/httpwg/http-core/issues/54>)
o Refactored Section 7, and added a section on timing attacks
(<https://github.com/httpwg/http-core/issues/233>)
o Changed "cacheable by default" to "heuristically cacheable"
throughout (<https://github.com/httpwg/http-core/issues/242>)
Index Index
A A
Age header field 21 Age header field 21
age 11 age 12
C C
Cache-Control header field 21 Cache-Control header field 22
cache 4 cache 4
cache entry 6
cache key 6 cache key 6
E E
Expires header field 29 Expires header field 30
explicit expiration time 11 explicit expiration time 12
F F
fresh 11 fresh 12
freshness lifetime 11 freshness lifetime 12
G G
Grammar Grammar
Age 21 Age 21
ALPHA 5 ALPHA 5
Cache-Control 22 Cache-Control 22
cache-directive 22 cache-directive 22
CR 5 CR 5
CRLF 5 CRLF 5
CTL 5 CTL 5
delta-seconds 6 delta-seconds 6
DIGIT 5 DIGIT 5
DQUOTE 5 DQUOTE 5
Expires 29 Expires 30
HEXDIG 5 HEXDIG 5
HTAB 5 HTAB 5
LF 5 LF 5
OCTET 5 OCTET 5
SP 5 SP 5
VCHAR 5 VCHAR 5
H H
heuristic expiration time 11 heuristic expiration time 12
heuristically cacheable 14
M M
max-age (cache directive) 22, 27 max-age (cache directive) 23, 28
max-stale (cache directive) 23 max-stale (cache directive) 23
min-fresh (cache directive) 23 min-fresh (cache directive) 24
must-revalidate (cache directive) 24 must-revalidate (cache directive) 25
N N
no-cache (cache directive) 23, 25 no-cache (cache directive) 24, 26
no-store (cache directive) 24, 26 no-store (cache directive) 24, 26
no-transform (cache directive) 24, 26 no-transform (cache directive) 25, 27
O O
only-if-cached (cache directive) 24 only-if-cached (cache directive) 25
P P
Pragma header field 30 Pragma header field 31
private (cache directive) 26 private (cache directive) 27
private cache 4 private cache 4
proxy-revalidate (cache directive) 27 proxy-revalidate (cache directive) 28
public (cache directive) 26 public (cache directive) 27
S S
s-maxage (cache directive) 27 s-maxage (cache directive) 28
shared cache 4 shared cache 4
stale 11 stale 12
strong validator 19 strong validator 19
V V
validator 16 validator 16
W W
Warning header field 30 Warning header field 31
Acknowledgments Acknowledgments
See Appendix "Acknowledgments" of [Semantics]. See Appendix "Acknowledgments" of [Semantics].
Authors' Addresses Authors' Addresses
Roy T. Fielding (editor) Roy T. Fielding (editor)
Adobe Adobe
345 Park Ave 345 Park Ave
San Jose, CA 95110 San Jose, CA 95110
USA United States of America
EMail: fielding@gbiv.com EMail: fielding@gbiv.com
URI: https://roy.gbiv.com/ URI: https://roy.gbiv.com/
Mark Nottingham (editor) Mark Nottingham (editor)
Fastly Fastly
EMail: mnot@mnot.net EMail: mnot@mnot.net
URI: https://www.mnot.net/ URI: https://www.mnot.net/
Julian F. Reschke (editor) Julian F. Reschke (editor)
greenbytes GmbH greenbytes GmbH
Hafenweg 16 Hafenweg 16
Muenster, NW 48155 Muenster 48155
Germany Germany
EMail: julian.reschke@greenbytes.de EMail: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/ URI: https://greenbytes.de/tech/webdav/
 End of changes. 61 change blocks. 
149 lines changed or deleted 207 lines changed or added

This html diff was produced by rfcdiff 1.46. The latest version is available from http://tools.ietf.org/tools/rfcdiff/