ファイルを提供するためのパスを書き換えるように設計されたASP.NETIHttpModule実装があります。モジュールは、次のように1つのイベントのみを処理PostAuthenticateRequest
します。
void context_PostAuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Path.ToLower().Contains("foobar"))
{
HttpContext.Current.RewritePath("virtdir/image.png");
}
}
パス「virtdir」は、アプリケーションの子の仮想ディレクトリです。アプリケーション自体は通常の場所で実行されます:C:\ inetpub \ wwwroot \ IisModuleCacheTest \仮想ディレクトリ「virtdir」はC:\TestVirtDir\にマップされます
のリクエストhttp://myserver/iismodulecachetest/foobar
は、予想どおり、仮想ディレクトリからimage.pngを返します。同様に、へのリクエストhttp://myserver/iismodulecachetest/virtdir/image.png
は同じ画像ファイルを返します。
次に、以下を実行します。
- リクエスト
http://myserver/iismodulecachetest/foobar
- C:\ testvirtdir \ image.pngを直接変更します(ペイントで色を変更して再保存します)。
- 繰り返す。
数秒間隔で1〜20回繰り返すと、返される画像は古くなったコピーになります。
動揺すると、サーバーは不明な時間が経過した後(10秒から数分まで)にのみ現在のバージョンを返します。手順1のURLをに置き換えてもhttp://myserver/iismodulecachetest/virtdir/image.png
、問題は発生していないようです。しかし不思議なことに、「foobar」URLを使用して問題が発生した後、直接URLも画像の古いコピーを返し始めます。
関連する詳細:
- アプリプールをリサイクルすると問題が解決します。
- しばらく待つと問題が解決します。
- ファイルを繰り返し再保存しても効果はないようです。「ファイルが変更された」イベントが失われたのではないかと思いましたが、一度スタックすると、半ダースの変更を保存でき、Iisstilは新しいコピーを返しません。
- web.configでキャッシュを無効にしても、違いはありません。
<caching enabled="false" enableKernelCache="false" />
- これが仮想ディレクトリであるという事実は重要であるように思われ、image.pngがアプリケーション自体のコンテンツの一部であるという問題を再現できませんでした。
- これはクライアントキャッシュではなく、間違いなく古いバージョンを返すサーバーです。別のブラウザを使用している場合でも、リクエストヘッダー、Ctrl + F5の更新を調べて、これを確認しました。
- この問題を2台のマシンで再現しました。Win7 Pro 6.1.7601 SP1 +IIS7.5.7600.16385およびServer2008R2 6.1.7601 SP1 +IIS7.5.7600.16385。
編集-詳細:
- サーバーレベルでキャッシュとカーネルキャッシュを無効にしても、違いはありません。
- URLに拡張子を追加しても、違いはありません
http://myserver/iismodulecachetest/foobar.png
。 - デバッガーをIISに接続すると、
context_PostAuthenticateRequest
イベントハンドラーが毎回トリガーされ、キャッシュがスタックしているかどうかに関係なく同じように動作していることがわかります。
Edit2-IISログ:
IISで「失敗した要求のトレース」を有効にしました(適切に構成されている場合でも、失敗していない要求に対してこれがどのように機能するかを調べます。パイプラインは、古いバージョンを返す要求がキャッシュヒットを明確に示すステップ17まで同じです。
最初のリクエストは、キャッシュミスがあり、問題なく表示されます。
しかし、スタックすると、キャッシュヒットが繰り返し表示されます。
キャッシュヒット後のイベントは、当然のことながら、キャッシュミスのシナリオとはかなり異なります。IISは、ファイルキャッシュが最新であると考えるのに完全に満足しているように見えますが、間違いなく最新ではありません。:(
スタックの少し下に、最初のリクエストが表示されます。
そして、その後の(障害のある)キャッシュヒット要求:
また、によると、ディレクトリは明らかに監視されていることに注意してくださいFileDirmoned="true"
。