Cloudfront - why is this not being "browser cached"? - caching

Here's the curl -I response to my Javascript file:
HTTP/1.1 200 OK
Content-Type: text/javascript
Content-Length: 72640
Connection: keep-alive
Date: Sat, 18 Feb 2017 16:12:06 GMT
Cache-Control: 86400
Last-Modified: Wed, 15 Feb 2017 15:09:28 GMT
ETag: "a6ee06ff5e49a4290bb2aabe5e0f9029"
Server: AmazonS3
Vary: Accept-Encoding
Age: 1173
X-Cache: Hit from cloudfront
Via: 1.1 3b17302562f1709d8b6c9f7be1.cloudfront.net (CloudFront)
I can see the Cache-Control tag there. Not sure what the Vary and the ETag are doing, but so be it. Does this somehow specify to a user's browser NOT to cache this file? Why are Pingdom or Goog PageSpeed not recognising this as a browser-cacheable file?

Your Cache-Control header is present, but the value is not actually valid. The correct format looks like this:
Cache-Control: max-age=86400
The number, by itself, is meaningless.
ETag: is the entity tag -- an opaque value that uniquely identifies the current content of a given URL. If the content changes, the ETag will also change. A browser with a cached copy may use this value for subsequent requests to ask that the server only return the content if it differs, by sending an If-None-Match: request header, including the last-seen ETag.
Vary: tells the browser that certain changes to the request may generate a different response. Unlike browsers, curl doesn't advertise its ability to support gzipped payload unless you specify the --compressed option. Adding that option when invoking curl triggers the addition of Accept-Encoding: gzip to the request, which may trigger the response to be compressed if you have that option enabled in CloudFront.

Related

Why is this file not cached in the browser? What's wrong with my headers?

I'm using Cloudfront (with Cloudflare in front) to serve the following file:
https://app.astrobin.com/assets/i18n/en.po?version=1623337803841
These are the response header at the time of writing:
accept-ranges: bytes
age: 2825
cf-cache-status: DYNAMIC
cf-ray: 65d3e1df6fe70f9a-VIE
cf-request-id: 0a984b7fa400000f9ac0139000000001
content-length: 6626
content-type: application/octet-stream
date: Thu, 10 Jun 2021 16:12:37 GMT
etag: "6336cef3a9da96c3c432813762cd7d70"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
last-modified: Thu, 10 Jun 2021 15:17:27 GMT
nel: {"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=TipuJtVNh6YvmqS4rzXv5mtQ%2BUKVHBvok88InKPm%2FNGqK13b2EX1%2BxMEuMfCgp4qslhW0xc1qeIzX1xpUzNW5u5rC8Di3lsb4zNqaoN0zhhH5E3wbizW%2FjlbqD5C"}],"group":"cf-nel","max_age":604800}
server: cloudflare
via: 1.1 3d4555926457517be3e728d2175d92a3.cloudfront.net (CloudFront)
x-amz-cf-id: MfDo647EBTxmyo7TZ-sseALca4bmzBPdPPnuiesvGjNnlkgqLzgwDA==
x-amz-cf-pop: VIE50-C2
x-cache: Hit from cloudfront
The following image is my Cloudfront "behavior" rule for that file:
I don't have any Page Rules in Cloudflare for this file.
I'm performing multiple requests to this file, for testing purposes, but the file is never fetched from Chrome's disk or memory cache. It always goes to the network.
As you can see from the request URL, I append the timestamp of the last known modification to this file, for cache-busting purposes, so I would like the file to be cached in the browser.
What am I missing?
Thanks!
Browser caching is determined by the caching headers (namely Cache-Control or Expires) in the response from the origin server. But the response you listed doesn't have such a header, so it's up to the browser to determine how long the resource is considered fresh.
If you want the browser to use a particular cache policy you should add a Cache-Control header to the response.

How to manage Cache with Google cloud storage

I have hosted a Website in the Google Cloud storage. Its has only static files. All are working good. I have changed few pages and uploading those files back to Cloud storage. It is successfully uploaded. But those changes are not reflecting while accessing through the browser immediately. It works after some time. I couldn't find the time pattern after when it reflects.
Could any one know how to reflect the changes immediately in the browser.
I have cleared all the cache and cookies. I have used control+F5 to refresh the page but it is not working. I have tested both Firefox and Chrome. Both behaves same.
I have copied the headers content below,
Request Headers
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Response Headers
X-GUploader-UploadID: AEnB2UpLL0HQXX5kBesLWzBDywY7Wyry1yA7WjPEnQT0YtH-Jg4PHl5kBHAGjqiATWSZ1-AJKX9IsrPbzP4lUZvtF2IAvbqxhA
Expires: Mon, 08 May 2017 16:59:50 GMT
Date: Mon, 08 May 2017 15:59:50 GMT
Last-Modified: Mon, 08 May 2017 15:53:53 GMT
Etag: "af73f0909ae13b8cc6298d8a58640046"
x-goog-generation: 1494258833242504
x-goog-metageneration: 1
x-goog-stored-content-encoding: identity
x-goog-stored-content-length: 24795
x-goog-meta-goog-reserved-file-mtime: 1494258821
Content-Type: text/html
Content-Language: en
x-goog-hash: crc32c=fOshiQ==, md5=r3PwkJrhO4zGKY2KWGQARg==
x-goog-storage-class: REGIONAL
Accept-Ranges: bytes
Content-Length: 24795
Server: UploadServer
Cache-Control: public, max-age=3600
Age: 2128
By default, Google itself caches publicly readable objects for up to an hour. Flushing your local cache won't help. You can change this behavior by specifying a specific cache control policy when uploading an object. You can also change this property after the fact, but it won't remove the object from the cache until the hour runs out.
You can also download the new version of the object by explicitly specifying its generation, or by appending some nonsense query parameter to the URL, like ?skipCache=1234.
See Related Google cloud storage: How can I reset edge cache?
Hope helps

Why Google Api fonts last-modified keep changing?

When I make a request to a Google Api font (e.g. https://fonts.googleapis.com/css?family=Roboto:400), the last-modified header is always changing to the current time.
Caching doesn't work as a result and the file has to be downloaded every load. Is there a reason for this? Should I download the file and host it on my server?
Should I download the file and host it on my server?
Absolutely not, because the content of the CSS files is dynamic and has different content for every user agent. This is because not all browsers support all font formats. Some require WOFF/WOFF2, others require EOT, TTF or SVG. By downloading and serving the file statically you will break font support for all other browsers.
Interestingly though, I do not see a last-modified header at all:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/css
Alt-Svc: clear
Alternate-Protocol: 443:quic,p=0
X-XSS-Protection: 1; mode=block
Server: GSE
Expires: Mon, 14 Dec 2015 09:14:21 GMT
Timing-Allow-Origin: *
Cache-Control: private, max-age=86400
Date: Mon, 14 Dec 2015 09:14:21 GMT
Content-Length: 222
Connection: close
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
The Expires header indeed is the same as the Date - so it expires at the time the ressource was loaded. The max-age option of Cache-Control though has higher precedence. So the file should be cached by the browser for 1 day.

When serving a response cached by the server, IIS 7 is stripping the Vary header

I’m using a custom framework for bundling stylesheets and scripts. (I.e., these are dynamically generated responses, not static files.)
The response for the initial request, when the response is being generated for the very first time, includes these headers:
HTTP/1.1 200 OK
Cache-Control: public, no-transform, max-age=31536000
Content-Type: text/css; charset=utf-8
Content-Encoding: gzip
Last-Modified: Mon, 25 Aug 2014 18:15:50 GMT
Vary: Accept-Encoding
Date: Tue, 09 Sep 2014 16:19:36 GMT
Content-Length: 3126
Now that the response above has been generated and cached by the server, subsequent requests for the same stylesheet are responded to with these headers:
HTTP/1.1 200 OK
Cache-Control: public, no-transform, max-age=31536000
Content-Type: text/css; charset=utf-8
Content-Encoding: gzip
Last-Modified: Mon, 25 Aug 2014 18:15:50 GMT
Date: Tue, 09 Sep 2014 16:20:00 GMT
Content-Length: 3126
Ignoring the new Date value, the headers are identical with the obvious exception of the missing Vary header.
One nasty consequence that I’ve seen in the wild is that if the very first response generated for a given asset is not compressed (due to the corresponding client not supporting compression), then the server caches that non-compressed response and serves it for all subsequent requests to all clients.
Any idea how to have the server retain the Vary header for cached responses?
I’m using HttpCacheability.Public for these responses. I can avoid the issue by using HttpCacheability.Private instead, but I’d prefer to allow the server and proxies to cache responses.
Some reading has led me to believe that IIS can’t do “kernel caching” if you vary by encoding. But I’m not sure if that means I can’t cache on the server at all or if it just prevents a special kind of server-side caching.
Update:
I was originally using the following to set the Vary header:
response.AppendHeader("Vary", "Accept-Encoding");
I tried a different method of specifying it:
response.Cache.SetVaryByCustom("Accept-Encoding");
That caused Vary to never be emitted. Not even on the very first response.
As a last resort, I’m also considering using:
response.Cache.SetNoServerCaching();
That causes the Cache-Control header to still specify public (so that proxies can still cache), but prevents the server from caching.
In line with the update I made to the question, I tried yet another way of specifying the Vary header:
response.Cache.VaryByHeaders["Accept-Encoding"] = true;
…And it fixed the problem. Responses now retain the Vary header across requests from multiple clients and are also cached by the server.

Why doesn't my expires headers make my files stay in cache?

I'm using valid expires and no-cache headers for my static files and they stay cached for as long as I keep browsing, but when I close my browser and use it back after a while I see the static files loading again, even when not refreshing with ctrl (+ shift) + r
I'm using Firefox, cache size set to 250MB and I don't let it remove any private or cached data.
Headers:
Accept-Ranges: bytes
Cache-Control: max-age=29030400, public
Content-Length: 142061
Content-Type: image/png
Date: Tue, 08 Dec 2009 19:18:43 GMT
Expires: Tue, 09 Nov 2010 19:18:43 GMT
Last-Modified: Sun, 18 Jan 2009 18:33:48 GMT
Server: Apache/2.2.14 (EL)
Which version of Firefox? Is the server sending Etags for the static files? You can view details about Firefox cache by going to the address about:cache and poking around. That will give you an idea of what Firefox is caching.
Update: After looking at your header tags, it seems as if the max-age value is set to a date that is way in the past and that is overriding the the value being set in the Expires header. See the HTTP 1.1 protocol definition at: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3.
If a response includes both an Expires
header and a max-age directive, the
max-age directive overrides the
Expires header, even if the Expires
header is more restrictive. This rule
allows an origin server to provide,
for a given response, a longer
expiration time to an HTTP/1.1 (or
later) cache than to an HTTP/1.0
cache. This might be useful if certain
HTTP/1.0 caches improperly calculate
ages or expiration times, perhaps due
to desynchronized clocks.
You will have to modify your Cache-Control header being sent by the server.

Resources