12

I'm trying to have a basic behavior regarding my caching strategy: files should be cached, and revalidated with server each time. So I would like Apache to send a 304 back.

Here is the dialog that happens for each browser refresh:

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

(this is from chrome devtools, with Disable cache unchecked)

You can see that the response contains the Cache-Control:No-cache Header, and that the If-modified-since header matches the Last-modified. The ETag matches too.

Shouldn't Apache sends a 304 in that case ?

EDIT

Disabling ETags in apache with

 Header  unset ETag

makes the caching behavior more predictible...

zrz
  • 263

4 Answers4

9

This seems to be an old bug, explaining why Header unset ETag makes a difference.

Apache 2.4.0+ automatically appends the compression method name to the ETag (as seen in your headers), and prevents a 304 response.

Newest versions of mod_deflate support a DeflateAlterETag that can be used to control this behavior:

DeflateAlterETag NoChange
1

This one stands out in the request as being a bit odd:

Cache-Control:max-age=0

Likely more important though, I notice that the returned content is html. Is it being dynamically generated? Apache MAY send a 304 response, but unless you're serving static content, it's not Apache's job to make that call, and it comes down to your application logic. E.g. most php applications have limited support for such things.

A front end cache may help, as the caching app can check the modification time, etag, etc., but only if both the application and the request headers are cache friendly. Eg the application has to set appropriate headers to indicate the content is cacheable, and things like the Cache-control header in your request will negate the cache. Your headers are not looking cache friendly.

mc0e
  • 5,979
0

Old bug solved in recent apache versions.

If DeflateAlterETag is not available to you, just install brotli compression and use BrotliAlterEtag NoChange

-1

If you have Apache configured with Cache-Control:No-cache, Apache will never send a HTTP 304 Not modified to the client.

If you want to revalidate some requests, put a Cache-Control:No-cache only on the pages where you need that. You don't need to revalidate all the resources, and you are wasting bandwidth by doing so.

ThoriumBR
  • 5,427