Я пытаюсь установить некоторые заголовки только для определенных location
блоки в nginx.
Проблема в том, что эти location
блоки содержат rewrite
операторы, которые, по-видимому, отбрасывают настраиваемые заголовки.
В этом примере мне нужны два правила:
/static
должен иметь expires max;
(который устанавливает заголовки Cache-Control: max-age=some huge value
и Expires: some future date really far off
) и переписать их имена на что-нибудь, что не содержит /static
Cache-Control: public
(нет max-age
)Вот конфигурация, которую я пробовал:
server {
listen [::]:80;
root /somepath;
location /static {
expires max;
rewrite /static(.*) /whatever$1;
}
add_header Cache-Control public;
}
И имеющая следующую структуру каталогов:
/somepath
/somepath/f1.txt
/somepath/static/f2.txt
Тогда получаем следующее:
f1.txt
: Cache-Control: public
нет Expires
заголовокf2.txt
: Cache-Control: public
нет Expires
заголовокЭто действительно для f1.txt
но нет f2.txt
. Я хочу, чтобы это было так:
f1.txt
: Cache-Control: public
нет Expires
заголовокf2.txt
: Cache-Control: max-age=some huge value
, Expires: some future date really far off
Я думаю, проблема в том, что rewrite /static(.*) /whatever$1;
строка, которая заставляет nginx отменить заголовки, которые он добавил до сих пор, а затем добавить их снова (таким образом повторно добавляя Cache-Control
). Таким образом, тривиальный обходной путь будет следующим:
server {
listen [::]:80;
root /somepath;
location /static {
rewrite /static(.*) /whatever$1;
}
location /whatever {
expires max;
}
add_header Cache-Control public;
}
Проблема в том, что в моем реальном файле конфигурации rewrite
выглядит не так дружелюбно. Переписанный URL-адрес нелегко сопоставить таким образом, который также не соответствовал бы некоторым файлам, которые не должны иметь expires max
, поэтому я не могу использовать этот обходной путь.
Есть ли способ закрепить эти заголовки после rewrite
?
РЕДАКТИРОВАТЬ: Вот как выглядят мои настоящие URL:
location ~ /(?:posts-)?img/.*-res- {
access_log off;
expires max;
rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2;
rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
}
Пока я могу добавить location
блок для /img
который позаботится о файлах, перезаписанных с использованием первого rewrite
правило, я не могу добавить один ко второму (/posts
) потому что некоторые файлы в /posts
не кэшируемые ресурсы и поэтому не должны иметь expires max
.
РЕДАКТИРОВАТЬ 2: Полный конфиг (или хотя бы содержащий все соответствующие части):
server {
listen [::]:80;
root /somepath;
server_name domain.tld;
location ~ /(?:posts-)?img/.*-res- {
access_log off;
expires max;
rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2;
rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
}
add_header Cache-Control public;
}
Структура каталога:
/somepath
/somepath/img/f1.png
/somepath/posts/post1.html
/somepath/posts/d1/f2.png
/somepath/posts/d2/f2.png
Ожидаемое поведение согласно HTTP-запросу:
GET /somepath
: Обслуживает /somepath
с участием Cache-Control: public
GET /somepath/img/f1.png
: Обслуживает /somepath/img/f1.png
с участием Cache-Control: public
GET /somepath/img/f1-res-whatever.png
: Обслуживает /somepath/img/f1.png
с заголовками, отправленными expires max
GET /somepath/posts/post1.html
: Обслуживает /somepath/posts/post1.html
с участием Cache-Control: public
GET /somepath/posts/d1/f2.png
: Обслуживает /somepath/posts/d1/f2.png
с участием Cache-Control: public
GET /somepath/posts-img/d1/f2-res-whatever.png
: Обслуживает /somepath/posts/d1/f2.png
с заголовками, отправленными expires max
Это должно сработать (хотя я проверил это с несколько более простой конфигурацией). Кстати, Игорь Сысоев рекомендует как можно реже использовать расположение регулярных выражений.
location /img {
if ($arg_max) { expires max; }
...
}
location /posts-img {
if ($arg_max) { expires max; }
...
}
location ~ /(?:posts-)?img/.*-res- {
access_log off;
expires max;
rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2?max=1;
rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2?max=1;
}
Для нечувствительности к регистру сопоставление местоположения.
location ~* /static/
без учета регистра удалите "*****"
location ~* /static/
Директива исходного кода Nginx документация