https://github.com/dvershinin/ngx_dynamic_etag
NGINX module for adding ETag to dynamic content
https://github.com/dvershinin/ngx_dynamic_etag
c etag etags module nginx nginx-module
Last synced: 5 months ago
JSON representation
NGINX module for adding ETag to dynamic content
- Host: GitHub
- URL: https://github.com/dvershinin/ngx_dynamic_etag
- Owner: dvershinin
- License: bsd-2-clause
- Created: 2019-01-26T16:06:46.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2025-01-03T04:00:07.000Z (9 months ago)
- Last Synced: 2025-05-06T21:05:25.598Z (5 months ago)
- Topics: c, etag, etags, module, nginx, nginx-module
- Language: C
- Homepage: https://www.getpagespeed.com/server-setup/nginx/nginx-enable-conditional-get-for-dynamic-pages
- Size: 48.8 KB
- Stars: 14
- Watchers: 2
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# ngx_dynamic_etag
[](https://travis-ci.org/dvershinin/ngx_dynamic_etag)
[](https://scan.coverity.com/projects/dvershinin-ngx_dynamic_etag)
[](https://www.buymeacoffee.com/dvershinin)This NGINX module empowers your dynamic content with automatic [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)
header. It allows client browsers to issue conditional `GET` requests to
dynamic pages. And thus saves bandwidth and ensures better performance!## Caveats first!
This module is a real hack: it calls a header filter from a body filter, etc.
The original author abandoned it, [having to say](https://github.com/kali/nginx-dynamic-etags/issues/2):
> It never really worked.I largely rewrote it to deal with existing obvious faults, but the key part with buffers,
which, myself being old, I probably wil l never understand, is untouched.To be reliable, the module has to read entire response and take a hash of it.
Reading entire response is against NGINX lightweight design.
I am not sure whether the buffer part waits for the entire response.Having said that, the tests which I added showcase that this whole stuff works!
Note that the `HEAD` requests will not have any `ETag` returned, because we have no data to play with,
since NGINX rightfully discards body for this request method.Consider this as a feature or a bug :-) If we remove this, then all `HEAD` requests end up having same `ETag` (hash on emptiness),
which is definitely worse.Thus, be sure you check headers like this:
```bash
curl -IL -X GET https://www.example.com/
```
And not like this:```bash
curl -IL https://www.example.com/
```
Another worthy thing to mention is that it makes little to no sense applying dynamic `ETag` on a page that changes on
each reload. E.g. I found I wasn't using the dynamic `ETag` with benefits, because of `= antispambot(get_option('admin_email')) ?>`,
in my WordPress theme's `header.php`, since in this function:> the selection is random and changes each time the function is called
To quickly check if your page is changing on reload, use:
```bash
diff <(curl http://www.example.com") <(curl http://www.example.com")
```Now that we're done with the "now you know" yada-yada, you can proceed with trying out this stuff :)
## Synopsis
```nginx
http {
server {
location ~ \.php$ {
dynamic_etag on;
fastcgi_pass ...;
}
}
}
```## Configuration directives
### `dynamic_etag`
- **syntax**: `dynamic_etag on|off|$var`
- **default**: `off`
- **context**: `http`, `server`, `location`, `if`Enables or disables applying ETag automatically.
### `dynamic_etag_types`
- **syntax**: `dynamic_etag_types [..]`
- **default**: `text/html`
- **context**: `http`, `server`, `location`Enables applying ETag automatically for the specified MIME types
in addition to `text/html`. The special value `*` matches any MIME type.
Responses with the `text/html` MIME type are always included.## Installation for stable NGINX
Pre-compiled module packages are available for virtually any RHEL-based distro like Rocky Linux, AlmaLinux, etc.
### Any distro with `yum`
```
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum install nginx-module-dynamic-etag
```### Any distro with `dnf`
```bash
sudo dnf -y install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf install nginx-module-dynamic-etag
```Follow the installation prompt to import GPG public key that is used for verifying packages.
Then add the following at the top of your `/etc/nginx/nginx.conf`:
```nginx
load_module modules/ngx_http_dynamic_etag_module.so;
```## Tips
You can use `map` directive for conditionally enabling dynamic `ETag` based on URLs, e.g.:
```nginx
map $request_uri $dyn_etag {
default "off";
/foo "on";
/bar "on";
}
server {
...
location / {
dynamic_etag $dyn_etag;
fastcgi_pass ...
}
}
```## Original author's README
Attempt at handling ETag / If-None-Match on proxied content.
I plan on using this to front a Varnish server using a lot of ESI.
It does kind of work, but... be aware, this is my first attempt at developing
a nginx plugin, and dealing with headers after having read the body was not
exactly in the how-to.Any comment and/or improvement and/or fork is welcome.
Thanks to http://github.com/kkung/nginx-static-etags/ for... inspiration.