バックグラウンド
私のアプリケーションの責任の一部は、制御された方法で静的リソース (CSS、JavaScript、画像) の要求を処理することです。いくつかのアプリケーション ロジックに基づいて、さまざまな時間にさまざまなユーザーにその URL で提供される可能性のあるさまざまなファイルの選択から 1 つを返します。したがって、これらは静的ファイルですが、動的な方法で配信されます。
アプリケーションは Symfony コンポーネントに基づいており、これらの静的なファイルの提供はBinaryFileResponse
クラスによって処理されます。
ブートストラップ コードは次のtrustXSendfileTypeHeader
メソッドを呼び出します。
\Symfony\Component\HttpFoundation\BinaryFileResponse::trustXSendfileTypeHeader();
アプリケーションは、構成と検出および使用に基づいて、いくつかの内部ロジックを使用して、apache_get_modules()
可用性を判断します。XSendfileが利用可能で、構成でそれを使用するように指定されている場合、ヘッダーが設定されますX-Sendfile-Type
。
if ($useHeader === true) {
$request->headers->set('X-Sendfile-Type', $header);
}
$response = new BinaryFileResponse($filename);
問題
XSendfile を使用しないように設定した構成でこれを実行するか、明らかに XSendfile をサポートしていない PHP 組み込み Web サーバーを介して実行すると、すべてが完璧です。
XSendfile を使用すると、ほとんどの場合、それも機能します。
ときどき、f5 キーを 3 ~ 4 回続けて押すと、「何か」が出てきて、文字化けした応答が返ってきます。たとえば、これは JavaScript ファイル (Firebug の「Net」の下の「Response」タブからコピー) であると想定されています。
hxYîãxHTTP/1.1 200 OK 日付: 2013 年 2 月 5 日火曜日 14:49:10 GMT サーバー: Apache/2.2.22 (Ubuntu) X-Powered-By: PHP/5.4.6-1ubuntu1.1 キャッシュ制御: public Last-Modified: Tue, 29 Jan 2013 13:33:23 GMT Accept-Ranges: bytes Content-Transfer-Encoding: binary ETag: "10426f-9f6-0" Vary: Accept-Encoding Content-Encoding: gzip Content-Length : 1011 キープアライブ: タイムアウト = 5、最大 = 98 接続: キープアライブ コンテンツ タイプ: アプリケーション/javascript
������VmoÛ6þ,ÿkÀ²ãIý°~q [Üt] XÑt¶H¤@Rv¼Àÿ}w(YS
ÀØ2yïå¹*¾Á>¯¥¥,è) Æ^Ât¸BaÆ\éjgäjí Î&ð*¸Åí¸tY!³Ç$Óe"jÞ![#,n®®oï®A¨þ¸þù××Þ©¼¼ôÇêÚd¹49mv°ÔrtBÖ^;WÍÓÔg´Y¥´FéôÁR9o°35Îà^º´N=UÐèEµ¢XE¸íÒ%ª°¨Úò7¬KñT¾{;£ÈrTnß³étUè{QÀçÍn·:'üJëQÍÄËZeNjOàyÕÁ:#3wö~4Òét1ù$µ
eN)RD| ¶FTØJ·ß½¥¨¸õGç >9TyÜxzgl-J:) b«9ûAQ½KXÉ!yÐÓ] óÆÎ@W¡?¢vún·7j©ÿ¢ðõÖGEÁy\ºp¤÷cKxf?ï*¼Éç0^ïîÌÇ°ñDQ¸mYJ|4t¾ñæËۯŠ¨6:çøp(}þÑò|LÂ;Õ(#v¹* /[¨U|xª æ]ÍyìjµòÛ¯p?4sI¥"v÷ôp|uQ4ò4&Ï·$eÒc¸ xo%7Ôi´2ñx;
TuÙj23 áÊ%ħ¿¹lÌwÀS.&ÏØß7¸}ó ZXzå k2'Zdùè ¦ºû-Ù[Ó²ÿU(¯¤¥=pÃjô¾ç]]Øhhô²× ÙãÚÍ4¨[!Õ}'Òþ^Ð�ûxÿ@+ÚVÞ~áÌáy?d aíD¹·U×ãÚ]õ5íão÷ÂAvUÆmÍaày`¦ä©A?mL[-}®(ÿË d°öò¬}Ç¢ ³Çp1À^6%0 hTô^ts´ÞíWô fO¶ö¢ÎNÜæ·HîUôÔ¶±ÌCµsxh.9åçi Û·_ÈÞØ_ÄãY_Ö}G<ì°ý2wÔ¿aw8/þù\ã±þ"0C oâh'tE¶À¤¥7I½éßRt. s?á^d|k/Æ)wRw÷cG¿<Þ ¼´°/^ø*ʤAVZ×y¿
応答本文にヘッダーが存在することに注意してください。残りの部分は明らかに JavaScript ではありません。また、最初に偽の文字がいくつかあります。これが、ヘッダーが本文にプッシュされる原因となる可能性があります。このコンテンツが gzip の結果であるかどうかを判断しようとしましたが、まだ確認できません。(以下の更新も参照してください)
質問
まず、BinaryFileResponse
テキスト (非バイナリ) ファイルを提供するために使用する正しいクラスはありますか? このクラスのドキュメントには、「BinaryFileResponse はファイルを配信する HTTP 応答を表す」としか書かれていません。これはあまり詳細ではありませんが、「バイナリ」ファイル専用であることについては何も述べていません。ただし、名前には独自の意味があります。なぜ Fabien はこのクラスを呼び出さなかったのFileResponse
ですか?
第二に、さらに重要なことは、これを引き起こしている可能性があるのは何ですか? Firefox と Chrome の両方で再現可能であるため、ブラウザの問題ではないと思います。これは XSendfile モジュールまたはBinaryFileResponse
クラスのバグですか? (以前は Symfony コンポーネント経由ではなく、より「生の」方法で使用したことがあり、そのような問題はなかったので、前者ではないと思う可能性があります)。
他の誰かがこれを経験しましたか?これを追跡するためにどこから始めるべきか考えていますか? 私はBinaryResponseFile
ソースコードを見てきましたが、実際には XSendfile ではあまり機能しません。関連するヘッダーを設定し、応答本文のコンテンツを防止するだけです。
アップデート
これらの文字化けした応答について、いくつかのことに気付きました。
- 送信される実際のヘッダーはまったくありません。つまり、Firebug の [ヘッダー] タブでは、文字化けした応答に対して、要求ヘッダーのみがリストされ、応答ヘッダーの見出しさえ表示されません。
- PHP で応答にカスタム ヘッダーを設定しても、そのヘッダーは文字化けした応答 (ヘッダーまたは応答本文) にはまったく表示されませんが、破損していない応答に対してはカスタム ヘッダーが正しく表示されます。