﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
377	etag не отдается с gzip	Владимир Андреев		"Обнаружил странное поведение при одновременно включенных директивах gzip и etag для отдачи статики.

Предположим, что мы уже делали запрос к ресурсу и он закеширован в браузере. После этого перевыкатываем изменения файлов на сервере. Далее делаем повторный запрос к ресурсу:
{{{
GET /css/reset.css HTTP/1.1
Host: example.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/css,*/*;q=0.1
If-None-Match: ""51bca012-41b""
If-Modified-Since: Sat, 15 Jun 2013 17:10:42 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Referer: http://example.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: _ym_visorc=w
}}}
{{{
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Sat, 15 Jun 2013 17:11:37 GMT
Content-Type: text/css
Last-Modified: Sat, 15 Jun 2013 17:11:34 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
}}}
Как видно, здесь нету заговка ETag. После этого обновляем страницу еще раз и видим вот такое:
{{{
GET /css/reset.css HTTP/1.1
Host: example.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/css,*/*;q=0.1
If-None-Match: ""51bca012-41b""
If-Modified-Since: Sat, 15 Jun 2013 17:11:34 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Referer: http://example.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: _ym_visorc=w
}}}
{{{
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Sat, 15 Jun 2013 17:11:53 GMT
Content-Type: text/css
Last-Modified: Sat, 15 Jun 2013 17:11:34 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
}}}

Т.е. браузер посылает дату модификации, полученную в ответ на первый запрос и etag, который остался еще от прежней версии файла (до выкатки изменений). NGINX видит, что первое условие выполняется, а второе нет, и отдает файл снова целиком. Если обновить страницу еще несколько раз, то увидим ту же самую картину.

Я не знаю, можно ли это назвать багом, но приведенный пример довольно типичный и отдавать 200 и весь файл целиком нехорошо.

Почему бы не отдавать ETag вместе с включенным сжатием? Это позволило бы устранить данную проблему.

P.S. А вот если перевыкатки на сервере не делать, то NGINX нормально отдает 304, причем вместе с заголовком ETag."	defect	closed	trivial		nginx-module		fixed	etag, gzip		Linux host-1 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux	"nginx version: nginx/1.4.1
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_spdy_module --with-ipv6"
