expires_in max-age cache control doesn't work - ruby-on-rails

I can't get the max-age cache control to work properly,
I have used expires_in that resulted in a "Cache-Control:max-age=86400, public, must-revalidate" header.
But yet, the browser still sends the request to the server, at least it is defined as "304 not modified", meaning that the ETag/If-None-Match headers works properly.
I have tested it with webrick on my localhost and on heroku,
with chrome 45 and Safari.
And no, my development tools are not opened, and the "disable cache" is not checked.
I also have tried to remove the ", must_revalidate: true" of the expires_in method call.
What am I missing?
Here is the output from the network in chrome:
General:
Remote Address:127.0.0.1:3000
Request URL:http://localtest.me:3000/api/books
Request Method:GET
Status Code:304 Not Modified
Response Headers:
Access-Control-Allow-Origin:*
Access-Control-Request-Method:*
Cache-Control:max-age=86400, public, must-revalidate
Connection:Keep-Alive
Date:Tue, 08 Sep 2015 13:28:01 GMT
Etag:W/"1f1b2d0b822830bc74e7c47a116205be"
Server:WEBrick/1.3.1 (Ruby/2.2.1/2015-02-26)
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:c70d4715-dcff-4558-85af-9d21556d406a
X-Runtime:0.553353
X-Xss-Protection:1; mode=block
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:en-US,en;q=0.8,fr;q=0.6,he;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Host:localtest.me:3000
If-None-Match:W/"1f1b2d0b822830bc74e7c47a116205be"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
And here is the ruby code:
before_action :cache_control, only: [:index, :show]
def cache_control
expires_in 1.day, public: true, must_revalidate: true
end

Well, the headers are fine, it is just a meter of how browsers treats the reload button or shortcut keys.
I found the answer here: https://stackoverflow.com/a/16510707/789658
Here are the findings in chrome:
Pressing Enter on the address bar respects the "max-age" and doesn't send a request to the server.
The reload button or Cmd+R sends a request to the server with If-Modified-Since and will return 304 if resource wasn't modified since...
Cmd+Shift+R sends a request to the server without even If-Modified-Since

Related

Loading font fron CloudFront giving No 'Access-Control-Allow-Origin' header is present on the requested resource

First, I know there are tons of similar issues on StackOverflow and elsewhere. I tried them for days with no luck. So sorry if this sounds duplicate. Correct me if it is actually.
I have Heroku Rails app loading font from CloudFront. Everything else seems to load fine except that font. I get
Access to Font at
'https://domainname.herokuapp.com/assets/LigatureSymbols-2.11-722bc1af51c5e458d52834d798e4c0e8.ttf'
from origin 'null' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
It says origin null, and access-control-allow-origin is not present. However this is the request and response data:
Request URL:https://domainname-herokuapp-com.global.ssl.fastly.net/assets/LigatureSymbols-2.11-722bc1af51c5e458d52834d798e4c0e8.ttf
Request Method:GET
Status Code:302 Found
Remote Address:151.101.0.249:443
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Accept-Ranges:bytes
Access-Control-Allow-Origin:*
Age:52
Connection:keep-alive
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Sun, 16 Apr 2017 10:40:37 GMT
Location:https://domainname.herokuapp.com/assets/LigatureSymbols-2.11-722bc1af51c5e458d52834d798e4c0e8.ttf
Server:gunicorn/19.7.1
Via:1.1 varnish
Via:1.1 vegur, 1.1 vegur
X-Cache:HIT
X-Cache-Hits:1
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Served-By:cache-hhn1527-HHN
X-Timer:S1492339237.333330,VS0,VE0
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:domainname-herokuapp-com.global.ssl.fastly.net
**Origin:https://staging.domainname.com**
Referer:https://domainname.herokuapp.com/assets/application-d2b73eea67437c851b6e71803bad2a6c.css
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Name
?store=true&search_type=posts
css?family=Lato:400,300,700
MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
LigatureSymbols-2.11-722bc1af51c5e458d52834d798e4c0e8.ttf
MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
icon-close-89c814d2fa53dff86b00936a7a8c836e.png
icon-bell-91b2c7d5db27d9fc9e8325dda55e73c0.png
icon-comment-35728eedd10ff36bc89c7a977ed67764.png
Origin is defined, and it should be allowing all origins. What am I doing wrong?

Rails http caching: Setting cache-control header not caching (not returning 305 not modified response) http page

I am on Rails 4 and learning http caching from here https://devcenter.heroku.com/articles/http-caching-ruby-rails
I am trying to set cache-control header with rails expires_in method. please see this link https://devcenter.heroku.com/articles/http-caching-ruby-rails#time-based-cache-headers
i am able to set cache-control value to max-age = 180. however when i refresh my web page again within 180 seconds after previous http request the request is hit to the rails entire stack again. i was expecting rails to return 305 not modified response because the cache-control header max-age value is set to 180 seconds.
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:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:_demo_app_session=elhZMUpaQkNJRGlwZG00R24vTEpyaWgzWCswckJ3eFU5bGFkM2lleGF3dDZOcnd1YXlyanNhY2lYb1pUTWJIZU4wK1FUNlRKWDh3LzVlamR0eUJrUFJ4c3UveFFyWVNWUHNCVHBGeGtYWTg2MmFmVnFTdU85TG96Vk5UOE5MMXFXWHBQYld0OTIxSFVId3lGZzdPSDVnPT0tLU5FZEhGbkppa0tkL0FQYkRYU0xPTUE9PQ%3D%3D--f8d61e1b9dd668b366e14271ac8412cb2579945a
Host:localhost:3000
If-None-Match:W/"bae944fae4d6e7f37fceeb0e4dd272c8"
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
Name
Path
Response headers
Cache-Control:max-age=120, public
Connection:Keep-Alive
Content-Length:3188
Content-Type:text/html; charset=utf-8
Date:Thu, 14 Apr 2016 17:39:08 GMT
Etag:W/"946d51d48e02b01a99af19862d2afc3e"
Server:WEBrick/1.3.1 (Ruby/2.2.1/2015-02-26)
Set-Cookie:_demo_app_session=TjFxZWlrT3hacFhhUEp0SXpTb3drNG9SeWZranV6TFlyc0dtRFpWUDFlRkY3eU90aEJPZTZNUmRlTThxQnF4SUxxM1g5QjVSUUxWYlUrd3NUbGxna0o0bHVMeXVHN0tiNUlSN2hndFE3a0U2Y28yemhzWUgzMWJIWCsyS0t2WFlLSWdmSWNuV0txVVJUYzhMZlA2eGRnPT0tLUhIZ1dHVkVZd05URFY2Y3ArQVBMU2c9PQ%3D%3D--f6bc45cb12c14978ed5df4ea3b136b80cb4cecaf; path=/; HttpOnly
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:bafba51d-480e-4597-9c1a-56785fdc4704
X-Runtime:0.013116
X-Xss-Protection:1; mode=block
Am i missing something here??

How in grails send with etag 302 status and not load js and other resource every time?

I add plugin
compile ":cache-headers:1.1.7"
and in config file next line:
cache.headers.enabled = false
now I'm sending this:
Request URL:http://localhost:8080/SomeProject/js/pages/somePage.js?_=1444319608606
Request Method:GET
Status Code:200 OK
Response Headers
view source
Accept-Ranges:bytes
Content-Length:3757
Content-Type:application/javascript
Date:Thu, 08 Oct 2015 15:56:09 GMT
ETag:W/"3757-1432890402118"
Last-Modified:Fri, 29 May 2015 09:06:42 GMT
Server:Apache-Coyote/1.1
Request Headers
view source
Accept:text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
Accept-Encoding:gzip, deflate, sdch
Accept-Language:ru,en-US;q=0.8,en;q=0.6,en-GB;q=0.4
Connection:keep-alive
Cookie:JSESSIONID=80DE99527007982AF9016B65B20E05D2; _ga=GA1.1.494624836.1438596076
Host:localhost:8080
Referer:http://localhost:8080/SomeProject/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
X-Requested-With:XMLHttpRequest
Query String Parameters
view source
view URL encoded
_:1444319608606
but how I understand in my request also should be:
If-Modified-Since,
If-None-Match
and after refresh I should get 302 status but I always get status 200.
You want a 304 status - 302 is a redirect. But the cache-headers plugin isn't what you want, that's for controller responses. The asset-pipeline plugin and its addon plugins manage caching, minification, etc. for static resources.

Rails 3.2 session_id never changes

I have a backbone app running on top of my Rails app, which is making a number of AJAX requests. Oddly enough, the session ID cookie that my browser stores never seems to change. I can see the next request being made and the reply returning success. The response still hangs on to the old session ID, however, and thus I can't logout or change user state in any way.
Here's an example of the headers being sent:
Request to /login.json:
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:_session_id=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJWY0YTI1Y2I5ZDE5MTgyYjJmN2MzMzZiMmE5ZWE2ZTAyBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTB1ZEozbzJCbUl4ZjluUDdCZVVEOXBhL0ZUeXNVRnFiMlFLblFTVUZPNGM9BjsARkkiDHVzZXJfaWQGOwBGaQg%3D--cf57849d4a4c0cbc5608574d959a772080b3afc5
Host:localhost:3000
If-None-Match:"7363e85fe9edee6f053a4b319588c086"
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
X-CSRF-Token:0udJ3o2BmIxf9nP7BeUD9pa/FTysUFqb2QKnQSUFO4c=
X-Requested-With:XMLHttpRequest
Response from /login.json:
Cache-Control:max-age=0, private, must-revalidate
Date:Tue, 15 May 2012 22:44:46 GMT
Etag:"7363e85fe9edee6f053a4b319588c086"
Server:WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Set-Cookie:_session_id=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWY0YTI1Y2I5ZDE5MTgyYjJmN2MzMzZiMmE5ZWE2ZTAyBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTB1ZEozbzJCbUl4ZjluUDdCZVVEOXBhL0ZUeXNVRnFiMlFLblFTVUZPNGM9BjsARg%3D%3D--b16d1f8e4bba3c86d5e3e9ece1ae50f1ad898d00; path=/; HttpOnly
X-Request-Id:8e278bdd3504257bcb9956e068ca3ca3
X-Runtime:0.014739
X-Ua-Compatible:IE=Edge
Notice it's giving me a new session ID. Yet when I make my next request...
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:_session_id=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJWY0YTI1Y2I5ZDE5MTgyYjJmN2MzMzZiMmE5ZWE2ZTAyBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTB1ZEozbzJCbUl4ZjluUDdCZVVEOXBhL0ZUeXNVRnFiMlFLblFTVUZPNGM9BjsARkkiDHVzZXJfaWQGOwBGaQg%3D--cf57849d4a4c0cbc5608574d959a772080b3afc5
Host:localhost:3000
If-None-Match:"53135bfd970c6b34f39ea3c4780ed240"
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
X-CSRF-Token:0udJ3o2BmIxf9nP7BeUD9pa/FTysUFqb2QKnQSUFO4c=
X-Requested-With:XMLHttpRequest
The cookie has never changed.
I figured it out. I had an async. request firing at the same time, so the browser was never getting a chance to get the proper session ID.

Internet Explorer blocked file download; file of "Unknown File Type"

I'm developing a front-end to a Rails application. In cross-browser testing, I immediately discovered that Internet Explorer (apparently all modern versions, but at least IE 7 and IE 8) is not correctly interpreting a file I'm trying to load via AJAX (with jQuery) as JavaScript. A file download warning appears and the user needs to confirm that the file should be downloaded. Unfortunately, this is not acceptable for the purposes of the application.
I created a couple of test files; one is just a JavaScript file served from Amazon S3; the other is actually a resource URL served by Varnish/Rails. The latter is the one that triggers the warning. So:
LINK: URL that gives a warning in IE
REQUEST HEADERS:
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
RESPONSE HEADERS:
Age: 1952
Cache-Control: public, max-age=3598
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 2060
Content-Type: text/javascript; charset=utf-8
Date: Fri, 13 Nov 2009 22:54:18 GMT
Etag: "272d9ec2e59aa92da18758cf42a4d729"
Server: nginx/0.7.61 + Phusion Passenger 2.2.5 (mod_rails/mod_rack)
Status: 200 OK
Via: 1.1 varnish
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.5
X-Runtime: 0.11573
X-Varnish: 176673116 176651738
LINK: URL that does not give a warning in IE
REQUEST HEADERS:
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
RESPONSE HEADERS:
Age: 14
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 52
Content-Type: text/javascript
Date: Fri, 13 Nov 2009 22:55:03 GMT
Etag: "7b7ded6696ee52551289c856d3173db4"
Last-Modified: Fri, 13 Nov 2009 22:30:45 GMT
Server: AmazonS3
Via: 1.1 varnish
X-Amz-Id-2: CR79uoLC67sr0e0uj4CUOCoBQgcIW/jaJc/FNSA3zsK3Lns/gAqx98/T9h/UeJGm
X-Amz-Request-Id: BCF2F2D69F5126DD
X-Varnish: 1566212056 1566211955
What immediately sticks out to me is the Content-Type of "text/javascript; charset=utf-8" for the URL that gives a warning - is that valid? I had always assumed that only "text/javascript" would be valid.
Also, the URL that gives a warning returns content of Content-Type "text/javascript," but it is a Rails URL that does not have an extension of .js - could that make a difference?
Is there anything else that sticks out, or does anyone have any other ideas of what could be causing this problem? Thanks very much for any help.
It's been some time and I've since forgotten the details of this problem, but I do know that the ultimate cause was due to a POST request that returned a Content-Type of "text/javascript."
Apparently, IE interprets POSTs that return "text/javascript" in the response headers as a security threat, which causes it to display the dreadful, and terribly uninformative, error message bar.
We changed the Content-Type of the response to "text/html" and that solved it!
First thing, I would try changing an extension to .js as you suggested. Internet Explorer has some nasty extension (among other things) based heuristics for determining document type.
It also sniffs the content in some cases, so the beginning should be typical for this type of a file (no weird characters, e.t.c.)
Make sure your JQuery statment looks something like this:
$.ajax({
type: "GET",
url: "test.js",
dataType: "script" // Defaults to HTML
});

Resources