AppCache(Symfony2)で最初の応答がプライベートである場合は問題ありませんか?


140

httpキャッシングを使用しようとしています。私のコントローラーでは、次のように応答を設定しています。

$response->setPublic();
$response->setMaxAge(120);
$response->setSharedMaxAge(120);
$response->setLastModified($lastModifiedAt);

開発モード

開発環境では、最初の応答は次のヘッダーを持つ200です。

cache-control:max-age=120, public, s-maxage=120
last-modified:Wed, 29 Feb 2012 19:00:00 GMT

次の2分間、すべての応答は次のヘッダーを持つ304です。

cache-control:max-age=120, public, s-maxage=120

これは基本的に私が期待していることです。

製品モード

製品モードでは、応答ヘッダーが異なります。app.phpでは、カーネルをAppCacheでラップしていることに注意してください。

最初の応答は、次のヘッダーを持つ200です。

cache-control:must-revalidate, no-cache, private
last-modified:Thu, 01 Mar 2012 11:17:35 GMT

したがって、これはキャッシュなしのプライベートレスポンスです。

次のリクエストはすべて、私が期待するものとほぼ同じです。次のヘッダーを持つ304:

cache-control:max-age=120, public, s-maxage=120

心配する必要がありますか?予想される動作ですか?

VarnishまたはAkamaiサーバーをその前に置くとどうなりますか?

少しデバッグを行ったところ、ヘッダーが最後に変更されたため、応答はプライベートであることがわかりました。HttpCacheカーネルはEsiResponseCacheStrategy使用して、キャッシュされた応答を更新します(HttpCache :: handle()メソッド)。

if (HttpKernelInterface::MASTER_REQUEST === $type) {
    $this->esiCacheStrategy->update($response);
}

EsiResponseCacheStrategy は、 Last-ResponseまたはETag(EsiResponseCacheStrategy :: add()メソッド)を使用する場合、応答をキャッシュ不可に変更します。

if ($response->isValidateable()) {
    $this->cacheable = false;
} else {
    // ... 
}

Response :: isValidateable()は、Last-ResponseまたはETagヘッダーが存在する場合にtrueを返します。

その結果、Cache-Controlヘッダー上書きさますEsiResponseCacheStrategy :: update()メソッド)。

if (!$this->cacheable) {
    $response->headers->set('Cache-Control', 'no-cache, must-revalidate');

    return;
}

Symfony2ユーザーグループでこの質問をしましたが、今のところ回答がありません:https : //groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

更新。

元のコードにアクセスできなくなったので、最新のSymfony標準版でシナリオ再現しようとしました。

応答ヘッダーの一貫性が向上しましたが、まだ間違っているようです。

Last-Modified応答にヘッダーを設定するとすぐに、ブラウザーによって行われた最初の応答には以下が含まれます。

Cache-Control:must-revalidate, no-cache, private

2番目の応答は期待されています:

Cache-Control:max-age=120, public, s-maxage=120

If-Modified-Sinceヘッダーの送信を回避すると、すべてのリクエストがを返しますmust-revalidate, no-cache, private

リクエストがで行われたprodか、dev環境で行われたかは関係ありません。


3
$ kernel = new AppCache($ kernel);を無効にすると、それは私に公開されていると示されています。しかし、それは常にコード200で応答します...私はreveryプロキシnginxとして使用します。
マイケル

あなたapp.phpapp_dev.php同じですか?(debugとenvは無視)
Florian Klein

1
そのプロジェクトへのアクセス権がなくなったため、確認できません。コントローラは、AppCacheが有効になっているデフォルトのコントローラだったことを覚えています。
Jakub Zalas

1
@Florian私は問題を再現してみましたが、Symfonyの最新バージョンでは動作が少し異なります(更新を参照)。
Jakub Zalas 2013

2
ヘッダーdebug=>trueを取得できるように、AppCacheのgetOptions()に設定しますX-Symfony-Cacheか?
電気式発電2013

回答:


9

私は同じ問題に直面しました。「公開」ヘッダーをcdnに指定する必要がありました。デフォルトでは、ゲートウェイキャッシングがprodモードで有効になっている場合、プライベートで200 OKを返し、nocacheはヘッダーを検証する必要があります。

私はこの方法で問題を解決しました。

app.phpで、ユーザーに応答を送信する前に($ respond-> send)、キャッシュコントロールヘッダーを空白に上書きし、キャッシュヘッダーをpublicおよびmax age(some value)に設定しました。

// app.phpからのコードスニペット

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        

コントローラでパブリックに設定されているにもかかわらず、プライベートレスポンスを受け取りましたか?
Jakub Zalas 14

はい、ゲートウェイキャッシングを有効にして、それをprodモードで実行すれば。静的コンテンツのための上記のソリューションが必要でした。
srikanthsatturi 2014

-4

あなたが経験する行動は意図されています。Symfony2 Docsは、privatepublicが使用される状況を明示的に説明します。デフォルトはprivateです。


これは私のケースではありません、申し訳ありません。
Jakub Zalas 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.