¿Está bien si la primera respuesta es privada con AppCache (Symfony2)?

140

Estoy tratando de usar el almacenamiento en caché http. En mi controlador, configuro una respuesta de la siguiente manera:

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

modo de desarrollo

En el entorno de desarrollo, la primera respuesta es 200 con los siguientes encabezados:

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

Para los próximos 2 minutos cada respuesta es un 304 con los siguientes encabezados:

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

Esto es básicamente lo que espero que sea.

modo de producción

En modo prod, los encabezados de respuesta son diferentes. Tenga en cuenta que en app.php envuelvo el núcleo en AppCache.

La primera respuesta es un 200 con los siguientes encabezados:

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

Entonces es una respuesta privada sin caché.

Cada próxima solicitud es más o menos lo que esperaría que fuera; un 304 con los siguientes encabezados:

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

¿Debería preocuparme por eso? ¿Es un comportamiento esperado?

¿Qué sucederá si pongo el servidor Varnish o Akamai delante?

Hice un poco de depuración y pensé que la respuesta es privada debido al último encabezado modificado. El núcleo HttpCache utiliza EsiResponseCacheStrategy para actualizar la respuesta en caché ( método HttpCache :: handle () ).

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

EsiResponseCacheStrategy convierte una respuesta en no almacenable en caché si usa Last-Response o ETag ( método EsiResponseCacheStrategy :: add () ):

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

Response :: isValidateable () devuelve verdadero si el encabezado Last-Response o ETag está presente.

Resulta sobreescribir el encabezado Cache-Control ( método EsiResponseCacheStrategy :: update () ):

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

    return;
}

Hice esta pregunta en el grupo de usuarios de Symfony2 pero hasta ahora no obtuve una respuesta: https://groups.google.com/d/topic/symfony2/6lpln11POq8/discussion

Actualizar.

Como ya no tengo acceso al código original, intenté reproducir el escenario con la última edición estándar de Symfony .

Los encabezados de respuesta son más consistentes ahora, pero aún así parecen estar equivocados.

Tan pronto como configuro un Last-Modifiedencabezado en la respuesta, la primera respuesta hecha por un navegador tiene un:

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

La segunda respuesta tiene un esperado:

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

Si evito enviar el If-Modified-Sinceencabezado, cada solicitud vuelve must-revalidate, no-cache, private.

No importa si la solicitud se hizo en prodo deventorno más.

Jakub Zalas
fuente
3
cuando desactivo $ kernel = new AppCache ($ kernel); se me muestra como público. pero siempre responderá con un código 200 ... lo uso como un proxy de recuperación nginx.
Michael
son tu app.phpy app_dev.phplo mismo? (ignorando depuración y env)
Florian Klein
1
Ya no tengo acceso a ese proyecto, así que no puedo confirmarlo. Recuerdo que los controladores eran los predeterminados con AppCache habilitado.
Jakub Zalas
1
@Florian Intenté reproducir el problema y tengo un comportamiento un poco diferente con la última versión de Symfony (ver una actualización).
Jakub Zalas
2
¿Establecería debug=>truegetOptions () en AppCache para obtener el X-Symfony-Cacheencabezado?
denkiryokuhatsuden

Respuestas:

9

Me he enfrentado al mismo problema. Tuve que suministrar encabezados 'públicos' mi cdn. De forma predeterminada, cuando el almacenamiento en caché de la puerta de enlace está habilitado en modo de producción, devuelve 200 OK con privado, nocache debe validar los encabezados.

Resolví el problema de esta manera.

En app.php, antes de enviar la respuesta al usuario ($ responder-> enviar), he sobrescrito el encabezado de control de caché en blanco y establecí los encabezados de caché en public y max age (algún valor).

// fragmento de código de app.php

    $response = $kernel->handle($request);
    $response->headers->set('Cache-Control', '');
    $response->setPublic();
    $response->setMaxAge(86400);
    $response->send();        
srikanthsatturi
fuente
¿Recibió respuestas privadas a pesar de que se pusieron públicas en un controlador?
Jakub Zalas
Sí, si habilito el almacenamiento en caché de la puerta de enlace y la ejecuto en modo prod. Necesitaba la solución anterior para contenidos estáticos.
srikanthsatturi
-4

El comportamiento que experimenta es el previsto. Los documentos de Symfony2 describen explícitamente las situaciones en las que se usan lo privado y lo público , por defecto es privado .

Udan
fuente
Este no es mi caso, lo siento.
Jakub Zalas