Search code examples
ruby-on-railsruby-on-rails-4.2http-caching

rails 4 http caching returning 200 iso 304, even with the same ETag and last_modified


I'm quite new to caching so I've been trying some different ways of caching my website. I've settled on HTTP caching now, because it's the most appropriate with sporadic updates and lots of users perusing the same pages over and over.

I'm struggling to get it working however. The site shows different content based on whether you're logged in or not, so I have to invalidate cache based on current_user as well as the latest update on the collection of models.

If I look in chrome inspect the ETag and the modified_since are the same, but the server returns a 200 instead of a 304. My code works in development environment, so I'm lost in how to troubleshoot it. Also a different page that only invalidates based on the collection of models (similar on latest update), does work as expected.

Code from the controller:

def index
  ...#some code

  # HTTTP caching:
  last_mod = @scraps.order("updated_at").last.updated_at
  user = current_user ? current_user.id : 0

  fresh_when etag: user.to_s, last_modified: last_mod, public: false
end

Output from chrome inspect

Response Headers:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Status: 200 OK
Last-Modified: Sun, 23 Jul 2017 20:40:53 GMT
Cache-Control: max-age=0, private, must-revalidate
ETag: W/"6e92592bdb6c3cf610020e2b076e64b4"
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Runtime: 3.187090
X-Request-Id: c698c0c6-8a0d-44ba-8ca9-3f162b766478
Date: Mon, 24 Jul 2017 14:49:38 GMT
Set-Cookie: ... [edited out]; path=/; HttpOnly
X-Powered-By: Phusion Passenger 5.0.30
Server: nginx/1.10.1 + Phusion Passenger 5.0.30
Content-Encoding: gzip

Request Headers:

GET /scraps?page=3&price_max=100&price_min=0&producer=silk+scraps HTTP/1.1
Host: www.picture-scraps.com
Connection: keep-alive
Accept: text/html, application/xhtml+xml, application/xml
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
X-XHR-Referer: https://www.picture-scraps.com/scraps?page=4&price_max=100&price_min=0&producer=silk+scraps
Referer: https://www.picture-scraps.com/scraps?page=4&price_max=100&price_min=0&producer=silk+scraps
Accept-Encoding: gzip, deflate, br
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4,af;q=0.2
Cookie: ... [edited out]
If-None-Match: W/"6e92592bdb6c3cf610020e2b076e64b4"
If-Modified-Since: Sun, 23 Jul 2017 20:40:53 GMT

I can imagine some additional information is needed, so please request and I'll add to the question.


Solution

  • Figured it out today. This post provides the answer. I saw the server used weak etags while in the dev environment strong etags were used. The latter is as expected as weak etags were only introduced from rails 5 forward.

    If you use Nginx with rails 4 you might experience the same problem. Installing rails_weak_etags gem solved it for me.