Skip to content

Instantly share code, notes, and snippets.

@ohbarye
Last active Jan 2, 2020
Embed
What would you like to do?

Issue

According to some references below, I assume nginx would downgrade strong etags to weak ones when it modifies response content (e.g. gzip compression). But nginx removes strong etags on gzip compression instead of a downgrade.

Step to reproduce

git clone https://gist.github.com/86f2d5b464f5e88821133c43a9cf4956.git
cd 86f2d5b464f5e88821133c43a9cf4956
docker-compose up -d

curl http://localhost:80/strong_etag -i -H "Accept-Encoding: gzip"

docker-compose up -d runs 2 nginx servers.

  1. proxy
    • It just does gzip compression of response. See proxy-nginx.conf.
  2. upstream
    • It just returns a JSON response with an etag. /weak_etag returns a weak etag, /strong_etag returns a strong one. See upstream-nginx.conf.

Expected behavior

HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Wed, 01 Jan 2020 11:34:44 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Encoding: gzip

�V�M-.NLOU�RP�H����Q(��,V����\�҂⒢��\E�Z5[,%

Actual behavior

  • Etag is removed.
HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Wed, 01 Jan 2020 11:34:44 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip

�V�M-.NLOU�RP�H����Q(��,V����\�҂⒢��\E�Z5[,%

Other information

When upstream returns a weak etag

  • The weak etag passes through the proxy nginx.
curl http://localhost:80/weak_etag -i -H "Accept-Encoding: gzip"
HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Wed, 01 Jan 2020 11:54:12 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Etag: W/d41d8cd98f00b204e9800998ecf8427e
Content-Encoding: gzip

�V�M-.NLOU�RP�H����Q(��,V����\�҂⒢��\E�Z5[,%

When gzip is off

  • The strong etag passes through the proxy nginx.
$ curl http://localhost:80/strong_etag -i
HTTP/1.1 200 OK
Server: nginx/1.17.6
Date: Wed, 01 Jan 2020 11:56:29 GMT
Content-Type: application/json
Content-Length: 44
Connection: keep-alive
Etag: d41d8cd98f00b204e9800998ecf8427e

{"message": "Hello, this is from upstream!"}%
version: '3'
services:
proxy:
image: nginx:1.17.6-alpine
ports:
- "80:80"
volumes:
- ./proxy-nginx.conf:/etc/nginx/nginx.conf
upstream:
image: nginx:1.17.6-alpine
volumes:
- ./upstream-nginx.conf:/etc/nginx/nginx.conf
events {
}
http {
server {
gzip on;
gzip_types application/json;
location / {
proxy_pass http://upstream:80;
}
}
}
events {
}
http {
server {
location /weak_etag {
add_header Etag W/d41d8cd98f00b204e9800998ecf8427e;
default_type application/json;
return 200 '{"message": "Hello, this is from upstream!"}';
}
location /strong_etag {
add_header Etag d41d8cd98f00b204e9800998ecf8427e;
default_type application/json;
return 200 '{"message": "Hello, this is from upstream!"}';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment