O Apache 2.4.7 ignora o cabeçalho de resposta Content-Encoding: identity, em vez disso, respeita Content-Encoding: none, definido pelo PHP

3

Acabei de perceber meu aparente problema (e a "solução" Content-Encoding: none da pergunta StackOverflow a que me referi na minha pergunta inicial, abaixo) pode muito bem ter sido simplesmente devido a um mal-entendido de como as coisas estão realmente funcionando. Por favor, revise meu adendo no final.

Em um aplicativo PHP que estou construindo, estou tentando gerenciar minha própria negociação e compactação de codificação de conteúdo.

Quando eu definir o cabeçalho de resposta Content-Encoding de dentro do PHP para gzip ou deflate , o Apache respeita isso. No entanto, quando eu o defino como identity , o Apache ignora isso e compacta a resposta.

Ele parece respeitar apenas o não-padrão Content-Encoding: none , como encontrei em algumas das respostas e seus comentários em esta pergunta sobre estouro de pilha .

Por isso, estou atualmente configurando-o para none , de dentro do PHP e, em seguida, alterando o cabeçalho por meio de .htaccess com:

Header edit Content-Encoding ^none$ identity

... mas isso realmente parece um hack feio. Eu gostaria de não ter que fazer isso, no caso de eu trocar de servidor, por exemplo.

Este é um problema conhecido e / ou este comportamento não padrão é documentado em algum lugar? Não consigo encontrar nenhuma documentação concreta sobre isso.

Eu também procurei o rastreador de bugs do Apache , mas só consegui para encontrar um relatório de erros tangencialmente relacionado , sobre o fato de o Apache não respeitar os valores do cabeçalho Accept-Encoding .

Adendo

Quando desativo o mod_deflate do Apache em .htaccess com (existem outras opções disponíveis para fazer isso também):

SetEnv no-gzip 1

... e defina Content-Encoding: identity dentro do PHP, o Apache mantém este cabeçalho e o conteúdo intactos, muito bem.

Portanto, eis o que acho que está realmente acontecendo :

Não é que Content-Encoding: none seja algum sinal oficial para o Apache para desabilitar a compactação ( Content-Encoding: bogus , por exemplo, produz o mesmo resultado), o que explicaria porque eu não encontrei nenhuma documentação sobre isso.

Em vez disso, é simplesmente um valor que não é um padrão RFC. Portanto, mod_deflate deixa o conteúdo intocado, assumindo que é uma codificação não padrão que não quer interferir.

Então, quando eu defino Content-Encoding: identity dentro do PHP, o mod_deflate provavelmente reconhece isso como um padrão RFC válido, significando que o conteúdo ainda não foi compactado e, já que o mod_deflate está habilitado, prossegue e o compacta.

Além disso, se eu definir Content-Encoding para gzip ou deflate , por exemplo, mod_deflate provavelmente deixará completamente intocado ou tentará compactá-lo de qualquer maneira, mas o algoritmo de compactação reconhece que o conteúdo já foi compactado.

Alguém pode confirmar se esta é uma interpretação correta do que realmente está acontecendo?

Então, uma possível solução seria desabilitar o mod_deflate para alguns arquivos / caminhos selecionados que o meu aplicativo PHP gerencia, ou até mesmo desabilitar o mod_deflate por completo / site-wide / server-wide se todos meu o conteúdo já foi compactado de alguma outra forma.

    
por Decent Dabbler 14.04.2017 / 15:50

1 resposta

0

Então, consegui resolver meus problemas, levando em conta as suposições que descrevi em minha pergunta, que parecem corretas. Mas não sem luta.

Ao tentar implementá-lo apenas para conteúdo gerado pelo PHP, encontrei alguns outros problemas, que descreverei aqui:

Inicialmente tive as seguintes regras de reescrita no meu .htaccess :

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [NC,L]

RewriteRule ^.*$ index.php [NC,L]

Com RewriteRule flags, você deve conseguir definir variáveis de ambiente . Então, imaginei que seria possível definir o E=no-gzip:1 flag apenas no último RewriteRule , fazendo:

RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L]

E mesmo que o mencionado anteriormente

SetEnv no-gzip 1

funcionou bem, a RewriteRule flag não iria perceber. Em seguida, examinei todos os tipos de perguntas relacionadas sobre o Stack Overflow, como essa este . Mas eles não ofereceram soluções satisfatórias.

Eu então recorri momentaneamente a definir a variável de ambiente de dentro do PHP com apache_setenv( 'no-gzip', 1 ); , o que fez o truque. Mas isso não parecia certo e também me fez perguntar por que o maldito RewriteRule flag não funcionaria tão bem.

Em seguida, decidi fazer um var_dump( $_SERVER ) , para ver se o sinalizador RewriteRule estava realmente definido, apenas para ser confrontado com um antigo inimigo que eu tinha esquecido :

array(39) {
  ["REDIRECT_no-gzip"]=>
  string(1) "1"
  ["REDIRECT_APP_ENV"]=>
  string(11) "development"
  /* etc. */
}

O maldito REDIRECT_ que é adicionado às variáveis de ambiente ao reescrever.

Tive a impressão de que a sinalização L no meu último RewriteRule deveria significar a interrupção de reescrita, mas aparentemente eu interpretei mal esta regra e suas condições:

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [NC,L]

Como RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L] reescreve para index.php , que é um arquivo normal ( -s ), as condições e regras mencionadas anteriormente ainda aparecem.

Agora que alterei essa regra para

RewriteRule !^index.php - [NC,L]

tudo está finalmente funcionando como desejado!

    
por 16.04.2017 / 09:38