Better caching with fewer false positives
Etag
Preliminaries
This note documents how Etags are created and processed by the server. Use of Etag headers is encouraged for reliable caching with fewer false positives.
The use of timestamps for conditional requests is not perfect, because the server and browser may not have their clocks precisely synchronized. The preferred solution to this problem is the use of etag
headers. An etag is a hashed value used as an identifier for a resource version. Whenever a resource is changed, its hashed value results in a new etag.
The protocol for using etags is similar to the protocol for conditional timestamps: 1) the original server response sends the resource together with an etag
header; 2) the browser saves the etag in its cache together with the resource; 3) conditional requests from the browser are sent with either a if-match
or if-none-match
header containing the saved etag value; 4) the server compares the resource's hashed value against the conditional etag value and responds with 304
and no payload if they match, or 200
and the resource in the payload if they differ.
See the note on Timestamps for the earlier protocol that does not use etags.
Etags are only applicable to HEAD
, GET
and PUT
requests. During a PUT
request, if the special header value '*'
is sent by the requestor, it means that the uploaded file should only be accepted if it doesn't already exist.
Configuration
The use of etags by the server is configured by setting the etag
entry to on
in the module
section. There are no other configuration settings required for its use.
Etag values are computed as an SHA1 hash of the file's modification time and file size. The full value is shortened to just the first six and last six hex digits of the hash to look something like "a1b2c3...8d9e0f"
.
Information Headers
If a PUT
request fails due to unmatched etags, a rw-if-match
or rw-if-none-match
information header is added to the response and a status code of 412
is returned.
EBNF
SP | ::= | U+20 |
CR | ::= | U+0D |
LEFT-CURLY-BRACKET | ::= | U+7B |
RIGHT-CURLY-BRACKET | ::= | U+7D |
etag-module-entry | ::= | 'etag' SP ('on' | 'off') CR |
modules-section | ::= | 'modules' SP LEFT-CURLY-BRACKET CR etag-module-entry † RIGHT-CURLY-BRACKET CR |
† Other modules omitted for brevity.
Cookbook
Example 1: etags disabled, fallback to timestamps
server {
modules {
etag off
}
}
Example 2: etags enabled, timestamps not used
server {
modules {
etag on
}
}
Review
Key points to remember:
- Etags are hashed values that uniquely identify a file's version.
- Etags are used for conditional requests.
- The use of etags is preferred over the use of conditional timestamps.