Hypertext Transfer Protocol (HTTP/1.1): Caching
Extracted elements (30)
HTTP cache requirements are focused on preventing a cache from storing non-reusable responses or reusing stored responses inappropriately, rather than mandating that caches always store and reuse particular responses. Caching is entirely OPTIONAL but reuse is assumed to be the default when no requirement or local configuration prevents it.
Pragma: no-cache is treated as equivalent to Cache-Control: no-cache in requests when no Cache-Control header is present, for backwards compatibility with HTTP/1.0 caches. Pragma has no specified meaning in responses and cannot reliably replace Cache-Control: no-cache there. Future extension pragmas are deprecated by this specification.
The qualified forms of the private and no-cache response directives (e.g., 'private=fieldname', 'no-cache=fieldname') are not widely implemented; many caches treat them as equivalent to the unqualified forms. Implementors should not rely on the selective field suppression behavior of these qualified forms.
A cache MUST ignore unrecognized cache directives. Cache-Control extensions are designed as modifiers to existing directives, with the old directive supplied alongside the new one, so that caches that do not understand the extension fall back to the behavior of the old directive.
A cache MUST invalidate the effective Request URI and URIs in Location and Content-Location response header fields upon receiving a non-error response to an unsafe request method. A cache MUST NOT invalidate a URI from Location or Content-Location if the host part differs from the effective request URI, to prevent denial-of-service attacks.
A cache MUST NOT generate a stale response if prohibited by no-store, no-cache, must-revalidate, s-maxage, or proxy-revalidate directives. A cache MUST NOT send stale responses unless disconnected or explicitly allowed (e.g., by max-stale request directive). A cache SHOULD add Warning: 110 when sending a stale response.
A cache MUST NOT reuse a stored response unless the effective request URI matches, the request method is compatible, all Vary-nominated selecting header fields match, no no-cache pragma or directive is present without successful validation, the stored response lacks no-cache without validation, and the stored response is fresh, allowed stale, or successfully validated.
A cache MUST NOT store a response unless the request method is understood and cacheable, the response status code is understood, no 'no-store' directive is present, the 'private' directive is absent (for shared caches), the Authorization header is absent (for shared caches, unless explicitly overridden), and the response contains an explicit expiration indicator, a cacheable-by-default status code, or a 'public' directive.
A cache MUST NOT use heuristics to determine freshness when an explicit expiration time is present in the stored response. Heuristics may only be used on responses whose status codes are defined as cacheable by default or that are marked explicitly cacheable. When a heuristic freshness lifetime exceeds 24 hours and current_age exceeds 24 hours, the cache SHOULD generate Warning: 113.
A cache recipient parsing a delta-seconds value MUST use an arithmetic type of at least 31 bits. If a value exceeds the representable range or causes overflow in subsequent calculations, the cache MUST treat the value as 2147483648 (2^31) or the greatest positive integer it can represent, ensuring overflow is detected and not treated as a negative value.
A shared cache MUST NOT use a cached response to a request with an Authorization header field to satisfy subsequent requests unless the response explicitly allows it via must-revalidate, public, or s-maxage directives. Responses with must-revalidate or s-maxage cannot be served stale by shared caches.
The must-revalidate response directive requires that once a response becomes stale, a cache MUST NOT use it to satisfy subsequent requests without successful origin-server validation. If the origin cannot be reached, the cache MUST generate a 504 (Gateway Timeout). This directive is intended for responses where serving stale content would cause incorrect operation (e.g., financial transactions).
The no-cache response directive indicates the response MUST NOT be used to satisfy a subsequent request without successful validation on the origin server. An optional field-name argument allows suppression of specific header fields only, while permitting caching of the remainder; however, this qualified form is not widely implemented.
The no-store request or response directive requires that a cache MUST NOT intentionally store any part of the request or response in non-volatile storage and MUST make a best-effort to remove it from volatile storage promptly. This directive is explicitly noted as NOT a reliable or sufficient mechanism for ensuring privacy.
The private response directive indicates the response MUST NOT be stored by a shared cache. An optional field-name argument limits this to specific header fields, allowing the rest of the response to be cached by shared caches. The 'private' label controls storage location only, not the confidentiality of message content.
When a stored response has a Vary header field, a cache MUST NOT use it unless all selecting header fields nominated by Vary match in both the original and presented request, after allowed normalizations. A Vary field-value of '*' always fails to match.
When a stored response is used to satisfy a request without validation, a cache MUST generate an Age header field equal to current_age. A cache MUST write through requests with unsafe methods to the origin server and MUST NOT generate a reply before forwarding the request and receiving a corresponding response.
Shared caches can expose browsing behavior as a timing side-channel: a second user sharing a cache may detect that another user visited a site because cached resources load faster. The no-store directive is not a reliable privacy mechanism since malicious or compromised caches might not honor it and communications networks may be vulnerable to eavesdropping.
A response is fresh when freshness_lifetime > current_age. Freshness lifetime is taken from the first matching source in priority order: s-maxage (shared caches only), then max-age, then Expires minus Date; otherwise heuristic freshness may apply. An explicit expiration time in the past forces the response to be stale.
Age is computed as: apparent_age = max(0, response_time - date_value); corrected_age_value = age_value + response_delay; corrected_initial_age = max(apparent_age, corrected_age_value); current_age = corrected_initial_age + resident_time. A cache MUST interpret corrected_age_value relative to when the request was initiated, not when the response was received.
Freshness lifetime priority for shared caches: (1) s-maxage, (2) max-age, (3) Expires minus Date. For private caches s-maxage is skipped. If multiple values exist for a single directive (e.g., two Expires fields), the value is considered invalid and the response should be treated as stale.
The Age header field (Age = delta-seconds) conveys the sender's estimate of seconds since the response was generated or validated at the origin server. Its presence implies the response was not freshly generated by the origin for this request. An HTTP/1.0 cache not implementing Age may omit it.
The Expires header field carries an HTTP-date timestamp after which the response is considered stale. A recipient MUST interpret invalid date formats (including '0') as representing a time in the past. If Cache-Control max-age or s-maxage is present, the Expires field MUST be ignored.
The primary cache key consists of the request method and target URI. When a response is subject to content negotiation via the Vary header field, secondary keys are formed from the values of the selecting header fields nominated by Vary, potentially resulting in multiple stored responses per primary key.
The s-maxage response directive overrides both max-age and Expires for shared caches and additionally implies proxy-revalidate semantics (responses with s-maxage=0 require revalidation before use). It is the highest-priority freshness source in the freshness lifetime calculation for shared caches.
Warning header codes are divided into 1xx (freshness/validation status — MUST be deleted after validation, only generated by caches during validation) and 2xx (persistent representation aspects — MUST NOT be deleted after validation unless a full response is sent). Defined codes: 110 (Stale), 111 (Revalidation Failed), 112 (Disconnected), 113 (Heuristic Expiration), 199 (Misc), 214 (Transformation Applied), 299 (Misc Persistent).
This document establishes the 'Hypertext Transfer Protocol (HTTP) Warn Codes' registry at IANA (http://www.iana.org/assignments/http-warn-codes), populated with warn codes 110, 111, 112, 113, 199, 214, and 299. Registrations must include a 3-digit warn code, short description, and specification pointer. New entries require IETF Review.
Cache poisoning attacks exploit implementation flaws or differences in message parsing between proxies and user agents to insert malicious responses into shared caches, distributing payloads to many clients. Cache contents persist after requests complete, making them attractive attack targets; cache contents must be treated as sensitive information.
Implementation flaws or misunderstanding of cache semantics may result in caching of sensitive information such as authentication credentials, exposing it to unauthorized parties. The Set-Cookie response header field does not inhibit caching; servers must use explicit Cache-Control directives to prevent caching of responses containing cookies.
Cache-Control ABNF: Cache-Control = 1#cache-directive; cache-directive = token [ '=' ( token / quoted-string ) ]. Directives are case-insensitive. Warning ABNF: warning-value = warn-code SP warn-agent SP warn-text [ SP warn-date ], where warn-code is a 3-digit integer. Age ABNF: Age = delta-seconds = 1*DIGIT.