nginx: Especifique cabeçalhos personalizados em blocos de localização reescritos

5

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
por Etienne Perot 21.12.2012 / 03:47

2 respostas

2

Isso deve funcionar (eu verifiquei isso com uma configuração um pouco mais simples, no entanto). Igor Sysoev recomenda a utilização de locais de regex o mínimo possível, a propósito.

    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;
    }
    
por 27.12.2012 / 15:41
0

Para correspondência de local insensível a maiúsculas e minúsculas.

location ~* /static/

insensível a maiúsculas e minúsculas remova o "*****"

location ~* /static/

Diretiva de localização do Nginx de origem documentação

    
por 24.12.2012 / 03:58