web-dev-qa-db-ja.com

Apache 2.4.7は、応答ヘッダーContent-Encoding:identityを無視し、代わりにContent-Encoding:noneを尊重し、PHP

私の明らかな問題(および、以下の最初の質問で参照したStackOverflowの質問からの「解決策」Content-Encoding: none)は、単に物事が実際にどのように機能しているかの誤解によるものである可能性があります。最後に私の補遺を確認してください。


私が構築しているPHPアプリケーションでは、独自のコンテンツエンコーディングネゴシエーションと圧縮を管理しようとしています。

PHPからgzipまたはdeflateのいずれかに応答ヘッダーContent-Encodingを設定すると、Apacheはこれを尊重します。ただし、 identity Apacheはこれを無視し、応答を圧縮します。

このStackOverflowの質問 の回答とコメントのいくつかで見つけたように、非標準のContent-Encoding: noneを尊重しているようです。

したがって、現在、PHP内から、noneに設定し、.htaccessを介してヘッダーを次のように変更しています。

Header edit Content-Encoding ^none$ identity

...しかし、これは本当に醜いハックのように感じます。たとえば、サーバーを切り替える場合に備えて、これを行う必要がないことを望みます。

これは既知の問題ですか、および/またはこの非標準の動作はどこかに文書化されていますか?これに関する具体的なドキュメントが見つからないようです。

私も Apacheのバグトラッカーを検索 しましたが、Accept-Encodingヘッダー値を尊重しないApacheについて 接線方向に関連するバグレポート しか見つかりませんでした。


補遺

.htaccessでApacheのmod_deflateを無効にすると(これを行うために利用できる他のオプションもあります):

SetEnv no-gzip 1

...そしてPHP内からContent-Encoding: identityを設定すると、Apacheはこのヘッダーとコンテンツをそのまま保持します。

したがって、これが実際に起こっていると私が思うことです:

Content-Encoding: noneが圧縮を無効にするためのApacheへの公式シグナルであるというわけではありません(たとえば、Content-Encoding: bogusは同じ結果を生成します)。これは、それに関するドキュメントが見つからなかった理由を説明します。

むしろ、それは単にRFC標準ではない値です。したがって、mod_deflateは、干渉したくない非標準のエンコーディングであると想定して、コンテンツをそのままにします。

したがって、PHP内からContent-Encoding: identityを設定すると、mod_deflateはおそらくこれを有効なRFC標準として認識し、コンテンツがまだ圧縮されていないことを示し、mod_deflateが有効になっているため、先に進んで圧縮します。

さらに、たとえばContent-Encodinggzipまたはdeflateに設定した場合、mod_deflateはおそらく完全にそのままにするか、とにかく圧縮しようとしますが、圧縮アルゴリズムはコンテンツはすでに圧縮されています。

誰かがこれが実際に起こっていることの正しい解釈であるかどうかをおそらく確認できますか?


したがって、考えられる解決策は、my PHPアプリケーションが管理するいくつかの選択されたファイル/パスに対してmod_deflateを無効にするか、allの場合はmod_deflateを完全に/サイト全体/サーバー全体で無効にすることです。 私のコンテンツはすでに他の方法で圧縮されています。

2
Decent Dabbler

ですから、質問で概説した正しいと思われる仮定を考慮に入れることで、問題を解決することができました。しかし、闘争なしではありません。

PHPで生成されたコンテンツのみに実装しようとすると、他のいくつかの問題が発生しました。これについては、ここで説明します。

私は当初、_.htaccess_に次の書き換えルールがありました。

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

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

RewriteRuleフラグを使用すると、 環境変数の設定 ができるはずです。したがって、次のようにすることで、最後のRewriteRuleだけに_E=no-gzip:1_フラグを設定できるはずだと考えました。

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

そして、前述の

_SetEnv no-gzip 1
_

正常に機能しましたが、RewriteRuleフラグはうまくいきませんでした。次に、これなど、StackOverflowに関するあらゆる種類の関連する質問を調べました これ 。しかし、彼らは満足のいく解決策を提供しませんでした。

次に、PHP with Apache_setenv( 'no-gzip', 1 );を使用して、環境変数を設定することに一時的に頼りましたが、それはうまくいきませんでした。しかし、それは正しくないと感じ、なぜくそーRewriteRuleフラグも同様に機能しません。

次に、var_dump( $_SERVER )を実行して、RewriteRuleフラグが実際に設定されているかどうかを確認しましたが、 忘れていた古い宿敵 :に直面するだけでした。

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

書き換え時に環境変数の前に付けられるくそー_REDIRECT__。

最後のLRewriteRuleフラグは書き換えを停止することを意味するはずだという印象を受けましたが、どうやらこのルールとその条件を誤って解釈したようです。

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

_RewriteRule ^.*$ index.php [NC,E=no-gzip:1,L]_は通常のファイル(_index.php_)である_-s_に書き換えられるため、前述の条件とルールが引き続き機能します。

そのルールをに変更したので

_RewriteRule !^index.php - [NC,L]
_

すべてが最終的に希望どおりに機能しています!

0
Decent Dabbler