Estou tentando definir alguns cabeçalhos apenas para blocos location
específicos no nginx.
O problema que tenho é que esses location
blocos contêm rewrite
declarações, que aparentemente parecem deixar cair os cabeçalhos personalizados.
Neste exemplo, tenho duas regras que desejo:
- Arquivos dentro de
/static
devem ter expires max;
(que define os cabeçalhos Cache-Control: max-age=some huge value
e Expires: some future date really far off
) e ter seus nomes reescritos para algo que não contenha /static
- Arquivos em todos os lugares devem ter
Cache-Control: public
(no max-age
)
Esta é a configuração que tentei:
server {
listen [::]:80;
root /somepath;
location /static {
expires max;
rewrite /static(.*) /whatever$1;
}
add_header Cache-Control public;
}
E com a seguinte estrutura de diretórios:
/somepath
/somepath/f1.txt
/somepath/static/f2.txt
Em seguida, obtemos o seguinte:
-
f1.txt
: Cache-Control: public
, não Expires
header
-
f2.txt
: Cache-Control: public
, não Expires
header
Isso é válido para f1.txt
, mas não f2.txt
. Eu quero que seja assim:
-
f1.txt
: Cache-Control: public
, não Expires
header
-
f2.txt
: Cache-Control: max-age=some huge value
, Expires: some future date really far off
O problema, eu acho, vem da linha rewrite /static(.*) /whatever$1;
, que faz o nginx cancelar os cabeçalhos que ele adicionou até o momento e então adicioná-los novamente (assim, re-adicionando Cache-Control
). Como tal, uma solução trivial seria esta:
server {
listen [::]:80;
root /somepath;
location /static {
rewrite /static(.*) /whatever$1;
}
location /whatever {
expires max;
}
add_header Cache-Control public;
}
O problema é que no meu arquivo de configuração real, o rewrite
não é tão amigável assim. A URL reescrita não é facilmente identificável de uma forma que também não corresponda a alguns arquivos que não devem ter expires max
, por isso não posso usar essa solução alternativa.
Existe uma maneira de colocar esses cabeçalhos após um rewrite
?
EDITAR : Veja como meus URLs reais se parecem:
location ~ /(?:posts-)?img/.*-res- {
access_log off;
expires max;
rewrite "/img/(.*)-res-.{8}(.*)" /img/$1$2;
rewrite "/posts-img/(.*)-res-.{8}(.*)" /posts/$1$2;
}
Embora eu possa adicionar um bloco location
para /img
que cuida dos arquivos que foram reescritos usando a primeira regra rewrite
, não posso adicionar um para o segundo ( /posts
) porque alguns arquivos em /posts
não são recursos que podem ser armazenados em cache e, portanto, não devem ter expires max
.
EDIT 2 : Configuração completa (ou pelo menos contendo todas as partes relevantes):
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;
}
Estrutura de diretórios:
/somepath
/somepath/img/f1.png
/somepath/posts/post1.html
/somepath/posts/d1/f2.png
/somepath/posts/d2/f2.png
Comportamento esperado de acordo com a solicitação HTTP:
-
GET /somepath
: veicula /somepath
com Cache-Control: public
-
GET /somepath/img/f1.png
: veicula /somepath/img/f1.png
com Cache-Control: public
-
GET /somepath/img/f1-res-whatever.png
: veicula /somepath/img/f1.png
com os cabeçalhos enviados por expires max
-
GET /somepath/posts/post1.html
: veicula /somepath/posts/post1.html
com Cache-Control: public
-
GET /somepath/posts/d1/f2.png
: veicula /somepath/posts/d1/f2.png
com Cache-Control: public
-
GET /somepath/posts-img/d1/f2-res-whatever.png
: veicula /somepath/posts/d1/f2.png
com os cabeçalhos enviados por expires max