Por que o Apache envia 200 OK enquanto a última modificação corresponde a If-modified-since?

10

Estou tentando ter um comportamento básico em relação à minha estratégia de cache: os arquivos devem ser armazenados em cache e revalidados com o servidor a cada vez. Então, eu gostaria que o Apache enviasse um 304 de volta.

Aqui está a caixa de diálogo que acontece para cada atualização do 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

(isto é do chrome devtools, com Desativar cache desmarcado)

Você pode ver que a resposta contém o cabeçalho Cache-Control: No-cache e que o cabeçalho If-modified-since corresponde ao Last-modified. O ETag também combina.

O Apache não deveria enviar um 304 nesse caso?

EDITAR

Desativando ETags no apache com

 Header  unset ETag

torna o comportamento do cache mais previsível ...

zrz
fonte
Eu acho que Cache-Control:max-age=0desativou o cache, então você vê a Cache-Control:No-cacheresposta.
ThoriumBR
Defino explicitamente Cache-Control: No-cache na minha configuração do apache porque de w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 , entendo que causa revalidação para cada solicitação. A revalidação implica reenviar o arquivo? Eu diria que ele deve usar Se-Modified-Since para determinar se é um 200 ou um 304
ZRZ

Respostas:

8

Este parece ser um bug antigo , explicando por que Header unset ETagfaz a diferença.

O Apache 2.4.0+ anexa automaticamente o nome do método de compactação ao ETag (como visto nos cabeçalhos) e evita uma resposta 304.

As versões mais recentes do mod_deflate suportam um DeflateAlterETag que pode ser usado para controlar esse comportamento:

DeflateAlterETag NoChange
Mathias R. Jessen
fonte
3
Isso está correto, mas o Apache 2.4 não contém essa opção, apenas o Apache 2.5. No entanto, pessoalmente, não acho ETags tão úteis, pois o Apache as baseia na data da última modificação, em vez do conteúdo do arquivo. Portanto, desativar o ETags volta ao cabeçalho If-Modified-Since, que é baseado na data da última modificação de qualquer maneira. Você pode alterar o ETag no Apache para torná-lo baseado no tamanho, modificado pela última vez e / ou inode - sendo o tamanho padrão e da última modificação o padrão - mas até que eles adicionem uma opção para calcular um ETag com base na soma de verificação do conteúdo do arquivo, é de uso limitado IMHO. Então eu os desligo.
Barry Pollard
1
@BazzaDP Isso faz sentido. 2.5 também tem uma DeflateAlterETag Removeopção de faz exatamente isso
Mathias R. Jessen
0

Este se destaca na solicitação como um pouco estranho:

Cache-Control:max-age=0

Provavelmente mais importante, notei que o conteúdo retornado é html. Está sendo gerado dinamicamente? O Apache PODE enviar uma resposta 304, mas, a menos que você esteja servindo conteúdo estático, não é tarefa do Apache fazer essa ligação, e tudo se resume à lógica da sua aplicação. Por exemplo, a maioria dos aplicativos php tem suporte limitado para essas coisas.

Um cache de front-end pode ajudar, pois o aplicativo de cache pode verificar a hora da modificação, a etag etc., mas apenas se os cabeçalhos do aplicativo e da solicitação forem compatíveis com o cache. Por exemplo, o aplicativo precisa definir cabeçalhos apropriados para indicar que o conteúdo pode ser armazenado em cache, e coisas como o cabeçalho de controle de cache em sua solicitação negarão o cache. Seus cabeçalhos não parecem amigáveis ​​ao cache.

mc0e
fonte
O arquivo solicitado é um arquivo html estático, para o qual o Apache acerta a hora da modificação. (Última modificação: terça-feira, 14 de outubro de 2014, 15:10:37 GMT). o cabeçalho max-age = 0 está na solicitação enviada pelo chrome quando digito o URL e pressiono Enter. Existe por causa de respostas anteriores?
ZRZ
Li que o Chrome adiciona automaticamente o Cache-Control: max-age = 0 a ser solicitado (exceto pela primeira vez que você carrega o Chrome, digite o URL, pressione enter). Mas isso não parece afetar outros servidores (as CDNs enviam 304 mesmo com max-age = 0 na solicitação).
Zrz 14/10
@zrz: limitar o cache intermediário é muito útil durante a depuração, mas de outra forma prejudicaria o desempenho. Verifique o contexto do que você lê sobre o que o chrome faz. Em termos do que o apache faz, é bastante configurável. O controle de cache é uma instrução para caches intermediários, não para o servidor de origem. No entanto, o apache pode atuar como um cache intermediário e pode ser configurado para fazer todo tipo de coisa. Acho que se você seguir suas instruções anti-cache, terá um comportamento mais parecido com o que espera de um servidor de origem.
Mc0e
0

Se você tiver o Apache configurado Cache-Control:No-cache, o Apache nunca enviará um HTTP 304 Not modifiedpara o cliente.

Se você deseja revalidar alguns pedidos, coloque Cache-Control:No-cacheapenas nas páginas em que você precisa. Você não precisa revalidar todos os recursos e está desperdiçando largura de banda ao fazer isso.

ThoriumBR
fonte
Pareço estar confuso com o termo "revalidar". Para mim, significa verificar se é um 304. Estou errado?
ZRZ
Você está errado. Revalidar é enviar todos os dados novamente para o cliente e forçá-lo a ler tudo novamente, mesmo que ele já tenha as mesmas informações. Você está basicamente desativando o cache em todos os clientes.
ThoriumBR
Isso explica muito. A última coisa que preciso explicar é que o Apache envia 304 para alguns recursos (png, por exemplo), enquanto eu ainda tenho que o Cache-Control não definiu nenhum cache na resposta e max-age = 0 na solicitação. Qualquer pista ?
ZRZ
@ThoriumBR Se eu o interpretei corretamente, as duas respostas estão incorretas aqui; sem cache (em oposição a sem armazenamento) não significa "não armazenar em cache" e pode resultar em 304 se o conteúdo não for alterado. Na verdade, o OP esperava isso, mas não o conseguiu devido ao problema do etag. must-revalidate refere-se à forma como o conteúdo obsoleto é tratado e nem sempre envia "os dados novamente".
26417 Nick