Хорошо ли, если первый ответ закрыт для AppCache (Symfony2)? - PullRequest
140 голосов
/ 05 марта 2012

Я пытаюсь использовать 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

Это в основном то, что я ожидаю.

режим работы

В режиме prod заголовки ответа отличаются. Обратите внимание, что в 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 () возвращает true, если присутствует заголовок Last-Response или ETag.

В результате перезаписывается заголовок 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

Update.

Так как у меня больше нет доступа к исходному коду, я попытался воспроизвести сценарий с последней стандартной версией 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.

Ответы [ 2 ]

8 голосов
/ 09 февраля 2014

Я столкнулся с той же проблемой.Я должен был предоставить «публичные» заголовки моего CDN.По умолчанию, когда кеширование шлюза включено в режиме prod, он возвращает 200 OK с частным, nocache должен проверить заголовки.

Я решил проблему таким образом.

В app.php, прежде чем я отправлю ответпользователю ($ response-> send) я перезаписал заголовок элемента управления кешем на пустой и установил заголовки кеша public и max age (некоторое значение).

// фрагмент кода из app.php

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
0 голосов
/ 23 октября 2013

Поведение, которое вы испытываете, предназначено. Symfony2 Docs явно описывает ситуации, когда используются private и public , по умолчанию private .

...