Можно ли, если первый ответ будет частным с помощью 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

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

прод-режим

В режиме 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

Обновить.

Поскольку у меня больше нет доступа к исходному коду, я попытался воспроизвести сценарий с последней стандартной версией 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то же? (игнорируя отладку и env)
Флориан Кляйн
1
У меня больше нет доступа к этому проекту, поэтому я не могу это подтвердить. Я помню, что контроллеры были по умолчанию с включенным AppCache.
Якуб Залас 09
1
@Florian Я попытался воспроизвести проблему, и у меня немного другое поведение с последней версией Symfony (см. Обновление).
Якуб Залас,
2
Не могли бы вы установить debug=>truegetOptions () в AppCache, чтобы получать X-Symfony-Cacheзаголовок?
denkiryokuhatsuden

Ответы:

9

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

Так я решил проблему.

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

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

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
шрикантхсаттури
источник
Вы получали частные ответы, несмотря на то, что они были открыты в контроллере?
Якуб Залас
Да, если я включу кеширование шлюза и запустил его в режиме prod. Мне нужно было вышеуказанное решение для статического содержимого.
srikanthsatturi
-4

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

Удан
источник
Это не мой случай, извините.
Якуб Залас