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