¿Cómo hacer que mod_cache funcione correctamente con contenido dinámico?

Estoy tratando de usar mod_cache para almacenar en caché el contenido generado dinámicamente. Esta es mi configuración de Apache:

CacheEnable mem /
MCacheSize 4096
MCacheMaxObjectCount 100
MCacheMinObjectSize 1
MCacheMaxObjectSize 2048
CacheIgnoreCacheControl On
CacheIgnoreNoLastMod On
CacheStorePrivate On
CacheStoreNoStore On

<Location /cgi-bin>
    SetHandler cgi-script
    Options +ExecCGI
</Location>

Y este es un script CGI (solo para probar):

#!/opt/app/phantomjs/bin/phantomjs
var date = new Date('Sun, 01 Jan 2012 00:00:00 GMT');
console.log('Last-Modified: '+ date.toUTCString());
console.log('Cache-Control: max-age=' + (365 * 24 * 60 * 60)+ ', public');
date.setDate(date.getDate() + 365);
console.log('Expires: '+ date.toUTCString() + '\n\n');

// lengthy operation here...

console.log(content);

Esto básicamente funciona. Pero lo que pasa es si un cliente solicita un cgi-bin con un If-Modified-Since encabezamiento:

  1. Encabezados de secuencias de comandos CGI
  2. unos segundos de retraso
  3. Cuerpo de secuencias de comandos CGI
  4. Apache envía 304

Eso no tiene sentido. Apache espera la respuesta completa antes de enviar una respuesta no modificada.

Lo que esperaba:

  1. Encabezados de secuencias de comandos CGI
  2. Apache envía 304
  3. Se cancela el guión CGI o se descarta el cuerpo del guión CGI

¿Hay alguna forma de hacerlo?

preguntado el 28 de agosto de 12 a las 09:08

Además, acabo de descubrir que mod_cache no parece tener ningún efecto cuando mi cgi-script establece explícitamente Status: 200, pero envía 304 si cgi no envía ningún encabezado de estado. -

2 Respuestas

El script CGI debe cambiarse de la siguiente manera.

  1. No utilice una fecha de última modificación estática. El Last-Modified debe establecerse para los recursos dinámicos en el tiempo de ejecución actual.

  2. La directiva de control de caché contiene un error de tipo 'pulic' debe ser 'público'

  3. La directiva Expires no es necesaria, porque Cache-Control tiene una prioridad más alta que Expires.

Su comportamiento esperado "terminar el script CGI" después de enviar el encabezado no es posible. Si su caché funciona, el script CGI no se ejecuta hasta que se invalida la entrada del caché.

Respondido 20 Jul 13, 18:07

1. lo anterior fue solo para probar. Pero el punto de la pregunta es que last-modified puede o no haber cambiado entre dos solicitudes (imagínese concatenar diferentes archivos...) 2. gracias por eso, aunque no cambió nada. 3. Prefiero quedarme Expires solo para estar extra seguro. 4. "el script CGI no se ejecuta hasta que se invalida la entrada de caché" ¿Cómo se supone que funciona con if-modified-since? - user123444555621

Aaaah - ahora entiendo lo que quieres decir. Su secuencia de comandos CGI debe enviar el estado 304 si sus recursos no han cambiado y cancelar el procesamiento posterior (cuerpo). Desde apache doc: cuando un servidor de origen recibe una solicitud condicional, el servidor de origen debe verificar si el parámetro ETag o Last-Modified ha cambiado, según corresponda para la solicitud. De lo contrario, el origen debe responder con una respuesta concisa "304 No modificado". Esto le indica a la memoria caché que el contenido obsoleto aún está actualizado y debe usarse para solicitudes posteriores hasta que se alcance nuevamente la vigencia de actualización del contenido: cyberflohr

Mod_cache satisface las solicitudes de clientes condicionales "si se modifica-since" si la entrada sigue siendo válida (tiempo válido) y cache_control (respuesta de origen) no contiene la directiva "debe revalidar". Por cierto: ¿Qué versión de apache usas? - cyberflohr

Derecha. Si bien Apache cumple con el requisito "el servidor de origen debe verificar si el parámetro ETag o Last-Modified ha cambiado" correctamente, lo hace esperando la respuesta completa. Lo que hace que el almacenamiento en caché sea inútil. Uso la versión 2.2, pero también podría usar 2.4 - user123444555621

... "Lo que hace que el almacenamiento en caché sea inútil". mi proyecto y encontré la respuesta, porque estamos reenviando solicitudes de recursos dinámicos a otras instancias de servidor y luego mod_cache funcionará. Vea el ejemplo en mi próxima publicación: cyberflohr

Esta es la solución de la que hablo en mi último comentario. Reenvíe la ejecución de CGI a un host virtual interno. Con esta configuración, mod_cache funcionará como se esperaba. Lo probé en mi máquina con apache 2.2.21.

# virtual cgi host - used internally only for cgi execution
<VirtualHost *:8080>
    ##ServerAdmin postmaster@dummy-host.localhost
    DocumentRoot "C:/Project/web"
    ServerName cgi-bin.local
    ErrorLog "logs/cgi-bin-error.log"
    CustomLog "logs/cgi-bin-access.log" combined
    LogLevel debug

    <Location /cgi-bin>
        SetHandler cgi-script
        Options +ExecCGI
    </Location>

</VirtualHost>

# Virtual host used by client
<VirtualHost *:8080>
    ##ServerAdmin postmaster@dummy-host.localhost
    DocumentRoot "C:/Project/web"
    ServerName web.local
    ErrorLog "logs/web-error.log"
    CustomLog "logs/web-access.log" combined

    CacheEnable mem /
    MCacheSize 4096
    MCacheMaxObjectCount 100
    MCacheMinObjectSize 50
    MCacheMaxObjectSize 20480
    MCacheMaxStreamingBuffer 20480
    CacheIgnoreCacheControl On
    CacheIgnoreNoLastMod On
    CacheStorePrivate On
    CacheStoreNoStore On

    ProxyRequests Off
    ProxyPass /cgn-bin http://cgi-bin.local:8080/
    ProxyPassReverse /cgn-bin http://cgi-bin.local:8080/

</VirtualHost>

Respondido 21 Jul 13, 16:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.