HTTP Conditional Requests
HTTP supports the notion of conditional requests, which are requests that are fulfilled depending on the result of executing a validator.
Usage
HTTP conditional requests are identical to standard HTTP requests, with the difference that they are only fulfilled by the server in cases where the specified validators pass. This type of HTTP request may be a bandwidth-conserving measure, where a copy of a resource is only retrieved if it is newer than the most recent one obtained by the client. Another use case is ensuring that a resource does not suffer from the problem of lost updates.
Validators
HTTP conditional requests rely on several different validators that are included as part of the HTTP request headers. They can be split into two types with the first one using the Last-Modified date property, and the second one relying on an Entity tag (ETag).
An ETag is a unique value that identifies the specific version of a resource. Servers maintain ETag values as a way of keeping track of documents either present or past.
Date format
The format of the date field stored in the Last-Modified property is as follows:
<day-name>, DD MMM YYYY, hh:mm:ss GMT
DD is the two-digit day number of the month.
MM refers to the month and has to be one of: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, or Dec.
YYYY refers to the four-digit year.
hh refers to the two-digit hour in 24-hour time format.
mm refers to the two-digit minute.
ss refers to the two-digit second.
GMT refers to Greenwich Mean Time and although it represents the time zone, this is not an option. All HTTP dates use GMT as a reference.
Note
The values for day-name and MM are case-sensitive.
Entity tag format
The ETag is specified as a string surrounded in quotes, such as:
ETag: “1234567890”
Strong validation versus weak validation
Depending on the application and implementation, different levels of validation may be required. The stricter type is strong validation, which requires that resources are 100% identical at the byte level. This is the required method for certain validators.
Weak validation is similar to strong validation, except that it only considers the contents of the resource. If, for example, two resources are identical but have a different date, then a weak validation check will pass, whereas a strong validation check will fail.
Both the Last-Modified property and ETags can be used for either strong or weak validation.
Entity tags are strong validators by default. However, it is possible to declare that an ETag is a weak validator by using the “W/” prefix, as in the following example.
ETag: W/“1234567890”
The “W/” modified is applied by the server to inform the client that the ETag does not cover every aspect of the resource. In other words, it is not as strict as a strong validator, and the client is entitled to know this before working with it.
Conditional request headers
The first group of validators relies on the Last-Modified property that is stored both locally and on the server. By comparing these dates, the client can determine whether they have the most recent version stored in the local cache.
If-Modified-Since: This validator passes if the resource has been modified since the specified date. This is useful if a resource is cached and the client wants to maintain the current one. Resources that have not been updated do not have to be re-downloaded.
If-Unmodified-Since: This validator will pass if the resource has not been modified since the specified date. This can be used to ensure that resources do not suffer from the lost update problem. Essentially, clients can verify that they are working with the current version.
The second group relies on the ETag property. An advantage to using ETags is that a specific version can be more easily pinpointed out of a set of resources. Another consideration is that if the date of a file-based resource is inadvertently updated, it will appear current, whereas it will not affect the ETag.
If-Match: This validator passes if the specified ETag matches that of the target resource.
If-None-Match: If there are no resources with the matching ETag then this passes.
The final validator is If-Range, which is used in conjunction with a Range Request. As in the case of a conditional request for a full resource, the success of the If-Range validation is required before it will be fulfilled. It can be used with either Last-Modified or ETag, but not with both specified in the same request. It is often used when resuming a file download, as it will ensure that the resource has not been modified since the last block was received.
Example
In this example, the client requests a resource and then stores it in the local cache. The ETag that accompanies the response uniquely identifies the particular version of the resource sent in the message body.
Sometime later, when the second HTTP request is made, the client includes the ETag with the If-Modified-Since validator. When the server recognizes that the resource has not been updated since it was last downloaded to the client, it returns the 304 Not Modified HTTP status code.
Finally, the client makes a third HTTP request, against passing the ETag in with it. This time, however, the resource has changed and upon recognizing that the client has an outdated version, the server transmits the most recent one. As part of the HTTP response, it includes the ETag for the new version.
Initial request
GET /news.html HTTP/1.1
Host: www.example.re
Initial response
HTTP/1.1 200 OK
Etag: “123400001”
Content-Type: text/html
Content-Length: 1250
<message body contains resource>
Second request
GET /news.html HTTP/1.1
Host: www.example.re
If-None-Match: “123400001”
Second response
HTTP/1.1 304 Not Modified
Etag: “123400001”
Third request
GET /news.html HTTP/1.1
Host: www.example.re
If-None-Match: “123400001”
Third response
HTTP/1.1 200 OK
Etag: “123400002”
Content-Type: text/html
Content-Length: 1500
<message body contains new resource>
Takeaway
HTTP conditional requests are used to improve network efficiency and data integrity. Several validators are used to check the state of a resource before it is downloaded or modified. This can be used as a bandwidth-conserving measure or gatekeeper for changes to a resource.