Estou executando um servidor web Apache, exibindo grandes imagens estáticas do sistema de arquivos. Configurei o servidor para retornar um cabeçalho de cache válido, assim:Header merge Cache-Control "public, max-age=31536000, immutable"
Está tudo muito bem, mas quando o usuário recarrega a imagem no navegador, o Apache nunca retorna uma 304 Not Modified
resposta.
Executei este comando curl (alterei o nome do host por motivos de confidencialidade):
curl -o /tmp/image.png -v -u test:example http://blah.example.com/static/images/covers/436g2gu94kxin4x7
Aqui estão os cabeçalhos de solicitação do 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
Eu esperava uma resposta 304, mas em vez disso recebi:
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
eu li oGuia de cache do Apache, mas nada disso parece relevante para esta situação… trata-se de configurar o próprio cache do Apache, seja na memória ou no disco, especialmente para suportar casos em que o Apache está servindo como proxy reverso para um servidor de origem.
Mas, neste caso, os arquivos já estão no disco local. Não há servidor de origem. Não quero/preciso que o Apache armazene uma cópia "em cache" separada do arquivo; Eu só quero que o Apache perceba que a Last-Modified
data do arquivo no disco corresponde à If-Modified-Since
data e retorna 304 Not Modified
nesse caso.
Como faço para configurar isso? Preciso fazer com que o Apache armazene sua própria cópia em cache separada dos arquivos para ativar GETs condicionais? (Será um cache muito grande, provavelmente armazenado em disco, o que é um desperdício total.)
Responder1
Primeiro, realmente não há cache?
É possível que curl seja o seu problema. Cansei seu código em uma URL que sei retornar 304, e ele sempre retorna 200 usando seu código acima. Você experimentou as ferramentas de desenvolvedor de um navegador da web? Contanto que "desativar cache" esteja desmarcado, você poderá atualizar seu URL e vê-lo retornar 304 na segunda atualização.
Em segundo lugar, pode ser um bug do Apache
Não vejo um cabeçalho ETag nos seus resultados. Supondo que o Apache realmente não esteja adicionando isso, provavelmente você poderá desconsiderar isso. Mas você ainda pode tentar adicionar isso às configurações do Apache, apenas para garantir:
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
(Certifique-se de ativar o mod de cabeçalhos com a2enmod headers
.)
Ou, melhor ainda, se você estiver no Apache versão 2.4.42 e posterior ( apache2 -v
), você pode tentar isso nas suas configurações:
<IfModule mod_deflate.c>
DeflateAlterETag NoChange
</IfModule>
Esse problema foi causado pelo módulo deflate adicionando o método de compactação ao final do ETag. Isso fez com que o Apache ignorasse o cache e sempre retornasse 200. Em suas próprias palavras, isto:
... evita a exibição de respostas "HTTP não modificado" (304) a solicitações condicionais de conteúdo compactado.
Portanto, desabilitar isso pode resolver alguns problemas de cache.