Tudo bem se a primeira resposta for privada com o AppCache (Symfony2)?


140

Estou tentando usar o cache http. No meu controlador, estou configurando uma resposta da seguinte maneira:

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

modo dev

No ambiente de desenvolvimento, a primeira resposta é 200, com os seguintes cabeçalhos:

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

Nos próximos 2 minutos, cada resposta é 304, com os seguintes cabeçalhos:

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

Isso é basicamente o que eu espero que seja.

modo prod

No modo prod, os cabeçalhos de resposta são diferentes. Observe que no app.php eu envolvo o kernel no AppCache.

A primeira resposta é 200, com os seguintes cabeçalhos:

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

Portanto, é uma resposta privada sem cache.

Cada próximo pedido é praticamente o que eu esperava; um 304 com os seguintes cabeçalhos:

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

Devo me preocupar com isso? É um comportamento esperado?

O que acontecerá se eu colocar o servidor Varnish ou Akamai na frente dele?

Fiz um pouco de depuração e achei que a resposta é privada por causa do cabeçalho da última modificação. O kernel HttpCache usa EsiResponseCacheStrategy para atualizar a resposta em cache ( método HttpCache :: handle () ).

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

EsiResponseCacheStrategy transforma uma resposta em não armazenável em cache se usar Last-Response ou ETag ( método EsiResponseCacheStrategy :: add () ):

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

Response :: isValidateable () retorna true se o cabeçalho Last-Response ou ETag estiver presente.

Isso resulta na substituição do cabeçalho Cache-Control ( método EsiResponseCacheStrategy :: update () ):

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

    return;
}

Fiz esta pergunta no grupo de usuários Symfony2, mas ainda não recebi uma resposta: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

Atualizar.

Como não tenho mais acesso ao código original, tentei reproduzir o cenário com a última edição padrão do Symfony .

Os cabeçalhos de resposta são mais consistentes agora, mas ainda parecem estar errados.

Assim que eu definir um Last-Modifiedcabeçalho para a resposta, a primeira resposta feita por um navegador terá:

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

A segunda resposta tem um esperado:

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

Se eu evitar enviar o If-Modified-Sincecabeçalho, todos os pedidos retornam must-revalidate, no-cache, private.

Não importa se a solicitação foi feita no ambiente prodou devmais.


3
quando desabilito o $ kernel = new AppCache ($ kernel); é mostrado como público para mim. mas, em seguida, ele sempre responderá com um código 200 ... eu uso como um proxy de devaneio nginx.
Michael

são o seu app.phpe app_dev.phpo mesmo? (ignorando depurar e env)
Florian Klein

1
Não tenho mais acesso a esse projeto, portanto não posso confirmar isso. Lembro-me de controladores padrão com o AppCache ativado.
Jakub Zalas

1
@ Florian Tentei reproduzir o problema e tenho um comportamento um pouco diferente com a versão mais recente do Symfony (consulte uma atualização).
Jakub Zalas

2
Você debug=>truedefiniria getOptions () no AppCache para obter o X-Symfony-Cachecabeçalho?
denkiryokuhatsuden

Respostas:


9

Eu enfrentei o mesmo problema. Eu tive que fornecer cabeçalhos 'públicos' meu CDN. Por padrão, quando o cache do gateway está ativado no modo prod, ele retorna 200 OK com privado, o nocache deve validar os cabeçalhos.

Eu resolvi o problema dessa maneira.

No app.php, antes de enviar resposta ao usuário ($ respon-> send), substituí o cabeçalho de controle de cache em branco e defina os cabeçalhos de cache para público e idade máxima (algum valor).

// trecho de código de app.php

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

Você obteve respostas privadas, apesar de elas terem sido públicas em um controlador?
Jakub Zalas

Sim, se eu ativar o cache do gateway e executá-lo no modo prod. Eu precisava da solução acima para conteúdo estático.
214149 srganthsatturi

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.