Cache Revalidate

Maxim Dounin mdounin at mdounin.ru
Wed Nov 27 14:06:41 UTC 2013


Hello!

On Tue, Nov 26, 2013 at 09:07:51PM -0500, S.A.N wrote:

> Есть досадные мелочи, которые хотелось бы исправить, при включении
> fastcgi_cache_revalidate on, параметр HTTP_IF_MODIFIED_SINCE, всегда
> отправляется на сервер, даже если кеша нет,  бекенду будет отправлен
> параметр с пустым значением.
> 
> По стандартам HTTP при отсутствии кеша, клиент не должен отправлять
> заголовок If-Modified-Since.
> Более правильно если Nginx так же как и браузеры, при отсутствии кеша не
> будет передавать в бекенд пустой хедер If-Modified-Since, т.е нет кеша нет
> хедера, сейчас приходится в конфиге писать 
> fastcgi_param HTTP_IF_MODIFIED_SINCE  $upstream_cache_last_modified
> if_not_empty;
> чтобы пустой хедер не приходил, как этого требует стандарт.

Да, это имеет смысл поправить. В proxy-то всё нормально, а вот в 
fastcgi/scgi/uwsgi из-за необходимости местами посылать пустые 
параметры - теперь уходит пустое значение в 
HTTP_IF_MODIFIED_SINCE.  Патч какой-то такой:

# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1385558623 -14400
#      Wed Nov 27 17:23:43 2013 +0400
# Node ID ca0cde10bf45b5a1d7c0574a1752dcde01b04061
# Parent  19afb15852d2b4c5354a24a2de25a33d5fa77364
Upstream: skip empty cache headers.

Notably this fixes HTTP_IF_MODIFIED_SINCE which was always sent with
cache enabled in fastcgi/scgi/uwsgi after 43ccaf8e8728.

diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2796,7 +2796,7 @@ ngx_http_fastcgi_merge_params(ngx_conf_t
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1506,7 +1506,7 @@ ngx_http_scgi_merge_params(ngx_conf_t *c
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1670,7 +1670,7 @@ ngx_http_uwsgi_merge_params(ngx_conf_t *
 
             s->key = h->key;
             s->value = h->value;
-            s->skip_empty = 0;
+            s->skip_empty = 1;
 
         next:
 

> Настроить subsecond ревалидацию в Nginx по стандартам HTTP тоже невозможно.
> Если бекенд отдает заголовок
> Cache-Control: max-age=0 и/или Expires: -1
> Nginx воспринимает их как указания не кешировать ответ, но по стандартам эти
> заголовки не запрещают кешировать они указывают клиенту что ответ сервера
> можно кешировать, но он сразу же устаревает и следущий запрос должен пройти
> ревалидацию, т.е клиент должен каждый запрос отправлять с хедерем
> If-Modified-Since.
> Мы нашли способ, как заставить Nginx кешировать такие ответы, отправить ему
> хедер
> X-Accel-Expires: @$time-1 
> Тогда Nginx ведет себя правильно, т.е. так же как браузеры, которым
> достаточно отправить Cache-Control: max-age=0
> Если, есть более красивое решения вместо X-Accel-Expires: @$time-1, хотелось
> бы его узнать. 

А use case какой?  С учётом характерных времён доступа по http - 
запрет кеширования даже на 1 секунду выглядит странно.

Вообще я склонен думать, что тот факт, что X-Accel-Expires в таком 
виде работает - это скорее баг.  Впрочем, можно его таким и 
оставить.

-- 
Maxim Dounin
http://nginx.org/en/donation.html



Подробная информация о списке рассылки nginx-ru