yum
upgrades for production use, this is the repository for you.
Active subscription is required.
What is Conditional GET
Conditional GET
is an essential part of HTTP protocol that revolves around ETag
and Last-Modified
headers. It allows for caches to validate with your server, whether it’s OK to use currently cached version of a web resource.
When a client has already cached a page (most browsers default to cache pages in absence of “negative” Cache-Control
header), upon next request it will simply send If-None-Match
(If-Modified-Since
) request asking whether content has changed.
If the content have not changed, server responds with 304 Not Modified
and empty response body. Thus saving time and traffic to download the same stuff all over again!
While most of web servers have ability to send the ETag
(or Last-Modified
) headers for static assets, only few web applications leverage those headers to improve their performance. Which means that the main page resources, e.g. PHP generated HTML documents, are not tagged properly, so they do not benefit from conditional requests at all.
10 years ago, I did blog about enabling Zend Framework with conditional GET
. But is there a more universal approach?
To implement conditional GET universally means that the web server (not the app!) will take some hash of request’s response and put it into ETag
header. It should then be able to handle If-None-Match
requests and emit a 304
response if the ETag
value provided by clients matches.
ngx_dynamic_etag
In my continuous journey of expanding nginx-extras collection, I have stumbled upon what seems to be an abandoned module, nginx-dynamic-etags. Something so useful for performance reasons, or rather golden in the age of non-stop chasing for performance tricks.
And so I’ve forked it as ngx_dynamic_etag which can be easily installed using our repository.
While being a novice to NGINX programming, I think I got many obvious issues sorted out. Mainly:
- Offload logic of matching ETag to NGINX core, here by setting
r->disable_not_modified = 0;
- Only generate ETag in locations where it is desired, here
- When your app already sends an
ETag
, it does not tamper with it, here
And of course, having it compiled as dynamic module and making it more lightweight / configurable through ETag
-ging only HTML responses by default.
How to install dynamic ETag module in CentOS / ReHat (6, 7, 8)
It is as easy as you thought if you already used our repository.
Step 1. Add GetPageSpeed extras YUM repository
Run the following command to add our repository:
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
Step 2. Install NGINX and ETag module
Then, all you have to do to install NGINX with ETag module:
sudo yum install nginx nginx-module-dynamic-etag
Follow the installation prompt to import GPG public key that is used for verifying packages.
Step 3. Enable dynamic ETag support in NGINX
Simply add the following at the top of your /etc/nginx/nginx.conf
:
load_module modules/ngx_http_dynamic_etag_module.so;
Now that NGINX has dynamic ETag capability, you can actually enable it for a location. An obvious one is PHP handler, so:
http {
server {
location ~ \.php$ {
dynamic_etag on;
fastcgi_pass ...;
}
}
}
Verify
To check that your page sends ETag
, you can use curl
:
curl -IL https://example.com/ | grep etag
Conditional GET requests can be easily verified in Chrome developer tools. Second reload of a cache-friendly resource will result in 304
(not modified) status:
That’s all there is to it. Now NGINX will generate ETag
for any HTML document produced by PHP!
CK
Can this module be used for setting etag with Nginx proxy cached file?