2

バックグラウンド

私のアプリケーションの責任の一部は、制御された方法で静的リソース (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 ではあまり機能しません。関連するヘッダーを設定し、応答本文のコンテンツを防止するだけです。

アップデート

これらの文字化けした応答について、いくつかのことに気付きました。

  1. 送信される実際のヘッダーはまったくありません。つまり、Firebug の [ヘッダー] タブでは、文字化けした応答に対して、要求ヘッダーのみがリストされ、応答ヘッダーの見出しさえ表示されません。
  2. PHP で応答にカスタム ヘッダーを設定しても、そのヘッダーは文字化けした応答 (ヘッダーまたは応答本文) にはまったく表示されませんが、破損していない応答に対してはカスタム ヘッダーが正しく表示されます。
4

1 に答える 1

2

まず、このApacheモジュールの経験はありませんが、一般的なエラーの推測について説明します。

より確実に再現できるか確認してください。Webブラウザーで試してみるのも問題ないかもしれませんがcurl、たとえばbashループを使用して、次のようなものを探してリクエストを複数回実行する必要がありますfor

for i in `seq 1 5`; do curl -v http://localhost/xsendfile-url; done

ヘッダーが設定されていて、実際のHTTPヘッダーの前に奇妙な文字がいくつかあるという事実から、毎回新しい接続が開かれるため、Connection: Keep-Alive別々の呼び出しではこの問題を再現できないと思います。curlしたがって、これを試して、奇妙な動作が発生するかどうかを確認してください(curlはデフォルトで有効になっています)。

curl -v http://localhost/xsendfile-url http://localhost/xsendfile-url http://localhost/xsendfile-url

これを使用して、プロジェクトのgithubの問題ページに移動し、調査結果を報告できます。おそらく、mod_xsendfileがそのように動作している理由、またはバグを見つけた理由を説明するのに役立ちます。

于 2013-02-14T12:10:55.687 に答える