Aplique a configuração httpd do Apache ao arquivo exato e nenhum subdiretório

2

Eu tenho um problema que parece ser simples. Eu quero aplicar um grupo de diretivas de configuração para um único arquivo (neste caso, myfile.html no DocumentRoot). Também pode haver subdiretórios contendo myfile.html , estes devem não obter a configuração. Eu também quero fazer sem usando Location ou LocationMatch .

Eu criei o seguinte

DocumentRoot "/home/amoe/opt/httpd/htdocs"
<DirectoryMatch "^/home/amoe/opt/httpd/htdocs$">
    <Files "myfile.html">
        ExpiresActive on
        ExpiresDefault A10
    </Files>
</DirectoryMatch>

No entanto, o cabeçalho Expires não é definido ao solicitar /myfile.html . Adicionar uma barra no final em DirectoryMatch parece não fazer diferença.

Você pode supor que eu quero fazer isso sem Location por motivos acadêmicos. (Edit: Além disso, para citar a documentação, É importante nunca usar ao tentar restringir o acesso a objetos no sistema de arquivos. )

    
por amoe 24.10.2016 / 17:37

1 resposta

2

A única maneira que encontrei para fazer esse trabalho é usando o seguinte:

<DirectoryMatch ^/home/amoe/opt/httpd/htdocs/[^/]+$>
    <Files "test.html">
        ExpiresActive on
        ExpiresDefault A10
    </Files>
</DirectoryMatch>

Acredito que o [^/]+ extra não seja necessário para que isso funcione, veja abaixo a explicação completa de como cheguei a essa conclusão e, como tal, acredito que isso seja um bug no Apache.

Todos os itens a seguir são baseados em um ambiente LTS do Ubuntu 16.04.1 que executa o Apache 2.4.23 com arquivos de teste nesses locais:

  • /path/test/test.html
  • /path/test/noheader-test.html
  • /path/test/child/test.html
  • /path/test/child/grandchild/test.html

Primeiramente, tentei várias variantes de expressão regular diferentes, todas as quais não foram compatíveis:

<DirectoryMatch ^/path/test$>
<DirectoryMatch ^/path/test/$>
<DirectoryMatch /path/test/$>
<Directory ~ ^/path/test$>
<Directory ~ ^/path/test/$>
<Directory ~ /path/test/$>

No entanto, descobri que, se você omitir a âncora EOL ( $ ), ela corresponderá a:

<DirectoryMatch ^/path/test/>
    <Files "test.html">
        ExpiresActive on
        ExpiresDefault A10
    </Files>
</Directory>

No entanto, este curso corresponde aos arquivos test.html em todos os subdiretórios:

  • /path/test/test.html - expira cabeçalho enviado
  • /path/test/noheader-test.html - no Expires cabeçalho enviado
  • /path/test/child/test.html - expira cabeçalho enviado
  • /path/test/child/grandchild/test.html - expira cabeçalho enviado

Era como se houvesse algo mais no caminho que o regex não estava correspondendo porque quando eu mudei o regex para ^/your/path/test/.+$ ele combinou.

Querendo saber o que era essa parte ausente do caminho, usei um grupo de captura regex e a diretiva Header para fazer com que o Apache me dissesse o que estava faltando:

<DirectoryMatch ^/path/test/(?<MISSINGPART>.+)$>
    <Files "test.html">
        Header add X-TEST "expr=%{env:MATCH_MISSINGPART}"
    </Files>
</DirectoryMatch>

Isso deu os seguintes cabeçalhos:

  • /path/test/test.html - x-test:"test.html"
  • /path/test/noheader-test.html - nenhum cabeçalho enviado
  • /path/test/child/test.html - x-test:"child/test.html"
  • /path/test/child/grandchild/test.html - x-test:"child/grandchild/test.html"

Isso sugere que DirectoryMatch está combinando com o nome do arquivo também!

No bug do Apache, o bug 41867 se encaixa nessa descrição, o que pode explicar isso (eu também testou isso sem a diretiva <Files> aninhada e os valores do cabeçalho permaneceram os mesmos)

Então, para provar, tentei substituir test.html no regex da seguinte forma:

<DirectoryMatch "^/path/test/test.html$">
    <Files "test.html">
        Header add X-TEST "Match"
    </Files>
</DirectoryMatch>

Nenhum cabeçalho X-TEST foi retornado.

Isso, no entanto, significa que o regex pode ser feito para corresponder a qualquer coisa que não seja um diretório após o diretório em que estamos interessados, assim:

<DirectoryMatch "^/path/test/[^/]+$">
    <Files "test.html">
        ExpiresActive on
        ExpiresDefault A10
    </Files>
</DirectoryMatch>

Isso dá o cabeçalho em todos os lugares desejados:

  • /path/test/test.html - expira cabeçalho enviado
  • /path/test/noheader-test.html - no Expires cabeçalho enviado
  • /path/test/child/test.html - no Expires cabeçalho enviado
  • /path/test/child/grandchild/test.html - no Expires cabeçalho enviado
por 28.10.2016 / 02:53