Чи добре, якщо перша відповідь приватна у AppCache (Symfony2)?


140

Я намагаюся використовувати кешування http. У своєму контролері я встановлюю відповідь так:

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

dev-режим

У середовищі розробників перша відповідь - це 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

Це в основному те, що я очікую, що це буде.

режим prod

У реальному режимі заголовки відповідей різні. Зауважте, що в app.php я загортаю ядро ​​в AppCache.

Перша відповідь - 200 із наступними заголовками:

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

Отже, це приватна відповідь без кешу.

Кожен наступний запит майже такий, який я б очікував, що це буде; a 304 із наступними заголовками:

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

Чи варто турбуватися про це? Це очікувана поведінка?

Що буде, якщо я поставлю перед ним сервер Varnish або Akamai?

Я трохи налагодив, і я зрозумів, що відповідь є приватною через останнє змінене заголовка. HttpCache ядро використовує EsiResponseCacheStrategy для поновлення (кешувати відповідь HttpCache :: ручка () метод).

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

EsiResponseCacheStrategy перетворює відповідь у не кешовану, якщо вона використовує Last-Response або ETag ( метод EsiResponseCacheStrategy :: add () ):

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

Response :: isValidateable () повертає значення true, якщо присутній Last-Response або заголовк ETag.

Це призводить до заміни заголовка кеш-керування ( метод 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

Друга відповідь очікується:

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 ... я використовую як відновлення проксі nginx.
Майкл

твоє app.phpі app_dev.phpте саме? (ігноруючи налагодження та оточення)
Флоріан Кляйн

1
Я більше не маю доступу до цього проекту, тому не можу підтвердити це. Я пам'ятаю, що контролери були типовими, увімкнено AppCache.
Якуб Залас

1
@Florian Я спробував відтворити проблему, і я мав дещо іншу поведінку з останньою версією Symfony (див. Оновлення).
Якуб Залас

2
Чи встановите ви debug=>truegetOptions () в AppCache, щоб ви отримали X-Symfony-Cacheзаголовок?
denkiryokuhatsuden

Відповіді:


9

Я зіткнувся з тією ж проблемою. Мені довелося поставляти "громадські" заголовки свого CDD. За замовчуванням, коли кеш-шлюз увімкнено в режимі prod, він повертає 200 ОК за допомогою приватних, nocache повинен перевірити заголовки.

Я вирішив проблему таким чином.

Перед тим, як надсилати відповідь користувачеві ($ respo-> відправити), у app.php я перезаписав заголовок кеша кеш на порожній і встановив заголовки кеша на загальнодоступні та максимальні вікові (деяке значення).

// фрагмент коду від app.php

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

Чи отримували ви приватні відповіді, незважаючи на те, що вони були відкриті в контролері?
Якуб Залас

Так, якщо я вмикаю кешування шлюзу і запускаю його в режимі prod. Мені знадобилося вище рішення для статичного вмісту.
srikanthsatturi

-4

Поведінка, яку ви переживаєте, призначена. Документи Symfony2 чітко описують ситуації, коли використовуються приватні та загальнодоступні , за замовчуванням - приватні .


Це не моя справа, вибачте.
Якуб Залас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.