What are conditional HTTP request headers


As the name says when making an HTTP request we can “condition” the result based on some inputs. This approach is used when we need a different response based on certain request criteria. These requests are usually used for saving bandwidth. In order for the conditional HTTP request to be issued, we needed to have a precondition to compare against. The best way to understand the conditional HTTP request headers we can look at the below examples.

The most common example where the conditional HTTP requests are made is when the browser wants to load the remote asset. The browser can decide not to spend bandwidth if the file on the remote server is the same as the one browser has in its own local cache.
When a browser sends the HTTP request for a remote asset it doesn’t have the precondition so, the conditional HTTP request can’t be made at that point. The precondition is created when a browser pulls the remote asset into a local cache. Then we’ll have HTTP headers we can compare to when making a conditional HTTP request:

HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 13:55:57 GMT
Content-Type: text/html
Content-Length: 4059
Connection: keep-alive
Last-Modified: Thu, 06 Aug 2020 11:56:10 GMT
ETag: "5f2befda-fdb"
Cache: HIT
Accept-Ranges: bytes

What we need the most for the conditional HTTP request is any of the conditional headers:

  • Last-Modified
  • ETag

Assuming the browser pulled in the file with above response headers, browser can make conditional HTTP request based on any of the above two headers:

$ curl -I http://bluegrid.io/ -H 'If-Modified-Since: Thu, 06 Aug 2020 11:56:10 GMT'
HTTP/1.1 304 Not Modified
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:20:10 GMT
Connection: keep-alive
Last-Modified: Thu, 06 Aug 2020 11:56:10 GMT
ETag: "5f2befda-fdb"
Cache: HIT

The status code generated for this scenario is 304 (Not Modified). This response tells us that if the browser made this request it wouldn’t bother spending bandwidth pulling the file to local. Instead, the browser uses the file it has stored in its local cache. Meaning that file on the server is the same as the one browser has in its local cache.

The same example can be tested using ETag value instead of Last-Modified:

$ curl -I http://bluegrid.io/ -H 'If-None-Match: "5f2befda-fdb"'
HTTP/1.1 304 Not Modified
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:24:17 GMT
Connection: keep-alive
Last-Modified: Thu, 06 Aug 2020 11:56:10 GMT
ETag: "5f2befda-fdb"
Cache: HIT

Other conditional HTTP request Headers

If-Modified-Since and If-None-Match are pretty effective and mostly used in conditional HTTP requests. There, however, are few others we should check out:

If-Match This HTTP request header requires the response body to be sent from the remote server if the ETag in local cache matches the one on the server:

$ curl -I http://bluegrid.io/ -H 'If-Match: "5f2befda-fdb"'
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:31:16 GMT
Content-Type: text/html
Content-Length: 4059
Connection: keep-alive
Last-Modified: Thu, 06 Aug 2020 11:56:10 GMT
ETag: "5f2befda-fdb"
Cache: HIT
Accept-Ranges: bytes

If, the ETag value in request changed a bit (adding a single letter at the end of it), the request would look like this:

$ curl -I http://bluegrid.io/ -H 'If-Match: "5f2befda-fdbc"'
HTTP/1.1 412 Precondition Failed
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:32:45 GMT
Content-Type: text/html
Content-Length: 189
Connection: keep-alive

This means that precondition we based this request on is not met – the ETag is not expected.

If-Unmodified-Since is conditioning response to be successful if the remote resource is dated before or up to the date in request:

$ curl -I http://bluegrid.io/ -H 'If-Unmodified-Since: "Thu, 06 Aug 2020 11:56:11 GMT"'
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:37:39 GMT
Content-Type: text/html
Content-Length: 4059
Connection: keep-alive
Last-Modified: Thu, 06 Aug 2020 11:56:10 GMT
ETag: "5f2befda-fdb"
Cache: HIT
Accept-Ranges: bytes

Now, let’s move the date more recent (by a single second):

$ curl -I http://bluegrid.io/ -H 'If-Unmodified-Since: "Thu, 06 Aug 2020 11:56:09 GMT"'
HTTP/1.1 412 Precondition Failed
Server: nginx/1.14.1
Date: Thu, 06 Aug 2020 14:37:27 GMT
Content-Type: text/html
Content-Length: 189
Connection: keep-alive

Voila!

Share this post

Share this link via

Or copy link