Kris
Kris

Reputation: 19948

Why is Rack::Cache not hitting cache when etag matches?

Starting with no cache on server or client

FIRST REQUEST

GET /post/1 HTTP/1.1

HTTP/1.1 200 OK
Date: Fri, 05 Mar 2010 09:05:46 GMT
Last-Modified: Thu, 04 Mar 2010 21:00:08 GMT
X-Rack-Cache: miss
Etag: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=3600, public

The Cache is missed and Rails gets hit and queries the database:

if stale?(:etag => @document, :last_modified => @document.updated_at.utc) # => true
  expires_in 1.hour, :public => true
  @post = Post.find(params[:id])
end

SECOND REQUEST

GET /post/1 HTTP/1.1
If-Modified-Since: Thu, 04 Mar 2010 21:00:08 GMT
If-None-Match: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified
Date: Fri, 05 Mar 2010 09:10:04 GMT
X-Rack-Cache: miss
Etag: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=3600, public

The Cache is missed and Rails gets hit, but this time it sends 304 Not Modified and the database is not hit:

if stale?(:etag => @document, :last_modified => @document.updated_at.utc) # => false
  expires_in 1.hour, :public => true
  @post = Post.find(params[:id])
end

However I was under the impression this should hit the Cache since the etag matches (If-None-Match/Etag)?

Upvotes: 1

Views: 4582

Answers (2)

mj1531
mj1531

Reputation: 2746

It's my understanding that the If-None-Match and If-Modified-Since headers are sent when the browser's cached content expires (the content has been in the browser's cache for more than the maxage in the Cache-Control header). This allows your application to verify that the content is still fresh and if it is, then send the 304 with a new maxage and the same Etag as before.

Upvotes: 0

Kris
Kris

Reputation: 19948

I'm doing a full refresh (F5) so the browser is adding Cache-Control: max-age=0 which is preventing the cache thinking the page is fresh.

Upvotes: 4

Related Questions