¿Por qué Apache envía 200 OK mientras coincide con la última modificación If-modified-since?

10

Estoy tratando de tener un comportamiento básico con respecto a mi estrategia de almacenamiento en caché: los archivos deben almacenarse en caché y revalidarse con el servidor cada vez. Así que me gustaría que Apache enviara un 304 de regreso.

Aquí está el diálogo que ocurre para cada actualización del navegador:

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(Esto es de Chrome Devtools, con Deshabilitar caché desmarcado)

Puede ver que la respuesta contiene Cache-Control: Encabezado sin caché, y que el encabezado If-modified-since coincide con Last-modified. El ETag también coincide.

¿No debería Apache enviar un 304 en ese caso?

EDITAR

Deshabilitar ETags en apache con

 Header  unset ETag

hace que el comportamiento de almacenamiento en caché sea más predecible ...

zrz
fuente
Creo que Cache-Control:max-age=0deshabilitó el caché, así que ves la Cache-Control:No-cacherespuesta.
ThoriumBR
Configuré explícitamente Cache-Control: No-cache en mi configuración de apache porque desde w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 , entiendo que causa la revalidación de cada solicitud. ¿La revalidación implica reenviar el archivo? Diría que debería usar If-modified-since para determinar si es un 200 o un 304.
zrz

Respuestas:

8

Esto parece ser un error viejo , que explica por qué Header unset ETaghace la diferencia.

Apache 2.4.0+ agrega automáticamente el nombre del método de compresión al ETag (como se ve en sus encabezados), y evita una respuesta 304.

Las versiones más recientes de mod_deflate admiten un DeflateAlterETag que se puede usar para controlar este comportamiento:

DeflateAlterETag NoChange
Mathias R. Jessen
fuente
3
Esto es correcto, pero Apache 2.4 no contiene esa opción, solo Apache 2.5. Sin embargo, personalmente no creo que los ETags sean tan útiles, ya que Apache los basa en la última fecha de modificación, en lugar del contenido del archivo. Por lo tanto, desactivar ETags vuelve al encabezado If-Modified-Since, que de todos modos se basa en la última fecha de modificación. Puede modificar el ETag en Apache para que se base en el tamaño, la última modificación y / o el inodo, siendo el tamaño y la última modificación los predeterminados, pero, hasta que agreguen una opción para calcular un ETag basado en la suma de comprobación del contenido del archivo, es de uso limitado en mi humilde opinión. Entonces los apago.
Barry Pollard
1
@BazzaDP Eso tiene sentido. 2.5 también tiene una DeflateAlterETag Removeopción para hacer exactamente eso
Mathias R. Jessen
0

Este se destaca en la solicitud como un poco extraño:

Cache-Control:max-age=0

Sin embargo, es probable que sea más importante, noto que el contenido devuelto es html. ¿Se está generando dinámicamente? Apache PUEDE enviar una respuesta 304, pero a menos que esté sirviendo contenido estático, no es el trabajo de Apache hacer esa llamada, y todo se reduce a la lógica de su aplicación. Por ejemplo, la mayoría de las aplicaciones php tienen soporte limitado para tales cosas.

Una caché de front-end puede ayudar, ya que la aplicación de almacenamiento en caché puede verificar el tiempo de modificación, etag, etc., pero solo si la aplicación y los encabezados de solicitud son compatibles con la caché. Por ejemplo, la aplicación debe establecer encabezados apropiados para indicar que el contenido se puede almacenar en caché, y cosas como el encabezado de control de caché en su solicitud negarán el caché. Sus encabezados no se ven amigables con el caché.

mc0e
fuente
El archivo solicitado es un archivo html estático, para el cual Apache obtiene el tiempo de modificación correcto. (Última modificación: martes, 14 de octubre de 2014 15:10:37 GMT). el encabezado max-age = 0 está en la solicitud enviada por Chrome cuando escribo la URL y presiono Enter. ¿Está ahí debido a respuestas anteriores?
zrz
Leí que Chrome agrega automáticamente Cache-Control: max-age = 0 a la solicitud (excepto la primera vez que cargue Chrome, escriba la URL, presione enter). Pero eso no parece afectar a otros servidores (los CDN envían 304 incluso con max-age = 0 en la solicitud).
zrz
@zrz: limitar el almacenamiento en caché intermedio es muy útil al depurar, pero de lo contrario dañaría el rendimiento. Comprueba el contexto de lo que lees en lo que hace Chrome. En términos de lo que hace apache, es bastante configurable. El control de caché es una instrucción para cachés intermedios, no para el servidor de origen. Sin embargo, apache puede actuar como un caché intermediario y puede configurarse para hacer todo tipo de cosas. Creo que si saca sus instrucciones contra el almacenamiento en caché, obtendrá un comportamiento más parecido al que espera de un servidor de origen.
mc0e
0

Si tiene Apache configurado con Cache-Control:No-cache, Apache nunca enviará un mensaje HTTP 304 Not modifiedal cliente.

Si desea revalidar algunas solicitudes, coloque Cache-Control:No-cachesolo en las páginas donde lo necesite. No necesita revalidar todos los recursos, y está desperdiciando ancho de banda al hacerlo.

ThoriumBR
fuente
Me parece estar confundido por el término "revalidar". Para mí, significa verificar si es un 304. ¿Me equivoco?
zrz
Está usted equivocado. Revalidar es enviar todos los datos nuevamente al cliente y obligarlo a leer todo nuevamente, incluso si ya tiene la misma información. Básicamente está deshabilitando el caché en cada cliente.
ThoriumBR
Eso explica mucho. Lo último que necesito explicar, teniendo en cuenta eso, es que Apache envía 304 para algunos recursos (png por ejemplo), mientras que todavía tengo que Cache-Control no estableció ningún caché en la respuesta y max-age = 0 en la solicitud. Cualquier pista ?
zrz
@ThoriumBR Si te he interpretado correctamente, ambas respuestas son incorrectas aquí; no-cache (en oposición a no-store) no significa "no cachear", y puede resultar en un 304 si el contenido no ha cambiado. De hecho, el OP esperaba esto, pero no lo estaba obteniendo debido al problema etag. must-revalidate se refiere a cómo se maneja el contenido obsoleto y no siempre envía "todos los datos nuevamente".
Nick