Demo HTTP caching with ETag

Written by Van Huong on Sep 4th, 2020 Views Report Post

Today we follow the client-server architecture using the HTTP protocol for most of our web apps. In fact, most of the hardest issues in production come from integration which means the HTTP headers may be modified by the proxy server. Therefore, the understanding of the headers is one of the key skills to resolve those issues.

For instance, let's explore how the header ETag works with a demo using Node.js as a server and curl as a client.

The flow

http-cache-etag.svg

Server Provision

I used Express for my webserver simply serving static files. I configured the HTTP header easily through passing the options of express.static middleware.

server.js

'use strict';

const express = require('express');

const PORT = process.env.PORT || 8080;

const app = express();

app.use(express.static('public', {
    etag: true
}));

app.listen(PORT, function() {
    console.log('Your server is running on port ' + PORT);
});

public/index.html

<!DOCTYPE html>
<html>
    <head><title>ETag demo</title></head>
    <body>
        <p>Hello World!</p>
    </body>
</html>

Inspect with cURL

Send an init request (without ETag)

curl -v http://localhost:8080
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Last-Modified: Fri, 04 Sep 2020 15:48:51 GMT
< ETag: W/"7b-17459ce6217"
< Content-Type: text/html; charset=UTF-8
< Content-Length: 123
< Date: Fri, 04 Sep 2020 15:51:32 GMT
< Connection: keep-alive
<
<!DOCTYPE html>
<html>
    <head><title>ETag demo</title></head>
    <body>
        <p>Hello World!</p>
    </body>
* Connection #0 to host localhost left intact
</html>* Closing connection 0

Send another request with If-None-Match header.

curl -v -H 'If-None-Match: W/"7b-17459ce6217"' http://localhost:8080
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
> If-None-Match: W/"7b-17459ce6217"
>
< HTTP/1.1 304 Not Modified
< X-Powered-By: Express
< Accept-Ranges: bytes
< Cache-Control: public, max-age=0
< Last-Modified: Fri, 04 Sep 2020 15:48:51 GMT
< ETag: W/"7b-17459ce6217"
< Date: Fri, 04 Sep 2020 15:54:01 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
* Closing connection 0

Comments (0)