Apache no ofrecerá respuestas 304 no modificadas para archivos estáticos

Apache no ofrecerá respuestas 304 no modificadas para archivos estáticos

Estoy ejecutando un servidor web Apache, que ofrece imágenes estáticas grandes fuera del sistema de archivos. He configurado el servidor para que devuelva un encabezado de caché válido, así:Header merge Cache-Control "public, max-age=31536000, immutable"

Eso está muy bien, pero cuando el usuario recarga la imagen en el navegador, Apache nunca devuelve una 304 Not Modifiedrespuesta.

Ejecuté este comando curl (cambié el nombre del host por razones de confidencialidad):

curl -o /tmp/image.png -v -u test:example http://blah.example.com/static/images/covers/436g2gu94kxin4x7

Aquí están los encabezados de solicitud de curl.

GET /static/images/covers/436g2gu94kxin4x7 HTTP/1.1
Host: blah.example.com
Authorization: Basic dGVzdDpleGFtcGxl
User-Agent: curl/7.64.1
Accept: */*
If-Modified-Since: Thu, 30 Apr 2020 02:21:47 GMT

Esperaba una respuesta 304, pero en lugar de eso obtuve:

HTTP/1.1 200 OK
Date: Fri, 28 Aug 2020 04:59:54 GMT
Server: Apache/2.4.25 (Debian)
Content-Type: image/png
Content-Length: 3115720
Last-Modified: Thu, 30 Apr 2020 02:21:47 GMT
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000, immutable

He leído elGuía de almacenamiento en caché de Apache, pero nada de eso parece relevante para esta situación... se trata de configurar el propio caché de Apache, ya sea en la memoria o en el disco, especialmente para admitir casos en los que Apache sirve como proxy inverso para un servidor de origen.

Pero en este caso, los archivos ya están en el disco local. No hay ningún servidor de origen. No quiero/necesito que Apache almacene una copia separada del archivo "en caché"; Solo quiero que Apache note que la Last-Modifiedfecha del archivo en el disco coincide con la If-Modified-Sincefecha y regresa 304 Not Modifieden ese caso.

¿Cómo configuro esto? ¿Tengo que hacer que Apache almacene su propia copia en caché separada de los archivos para habilitar GET condicionales? (Será un caché muy grande, presumiblemente almacenado en el disco, lo cual es un desperdicio total).

Respuesta1

En primer lugar, ¿realmente no se trata de almacenamiento en caché?

Es posible que el rizo sea tu problema. Cansé tu código en una URL que sé que devuelve 304 y siempre devuelve 200 usando tu código anterior. ¿Probaste las herramientas de desarrollo de un navegador web? Siempre que "deshabilitar el almacenamiento en caché" no esté marcado, debería poder actualizar su URL y ver que devuelve 304 en la segunda actualización.

En segundo lugar, podría ser un error de Apache.

No veo un encabezado ETag en tus resultados. Suponiendo que Apache realmente no agregue esto, entonces probablemente pueda ignorarlo. Pero aún puedes intentar agregar esto a tu configuración de Apache, por si acaso:

<IfModule mod_headers.c>
    Header unset ETag
</IfModule>
FileETag None

(Asegúrese de habilitar el mod de encabezados con a2enmod headers).

O, mejor aún, si tienes la versión 2.4.42 y posterior de Apache ( apache2 -v), puedes probar esto en tu configuración:

<IfModule mod_deflate.c>
    DeflateAlterETag NoChange
</IfModule>

Este problema se debió a que el módulo deflate agregó el método de compresión al final de la ETag. Esto hizo que Apache ignorara el almacenamiento en caché y siempre devolviera 200. En sus propias palabras, esto:

...impide servir respuestas "HTTP no modificado" (304) a solicitudes condicionales de contenido comprimido.

Módulo Apache mod_deflate

Entonces, deshabilitarlo puede resolver algunos problemas de almacenamiento en caché.

información relacionada