Will ETag work without cache-control header set by web server - caching

My server returns the following headers for a file:
Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:155
Content-Type:text/css
Date:Thu, 06 Feb 2014 18:32:44 GMT
ETag:"99000000061b06-9b-4f1c118fdd2f1"
Keep-Alive:timeout=5, max=100
Last-Modified:Thu, 06 Feb 2014 18:32:37 GMT
As you can see, it doesn't return cache-control header, however it returns ETag and Last-Modified headers.
My question is whether browser is going to cache the requested file? I can observr that during the following requests the browser sends ETag:"99000000061b06-9b-4f1c118fdd2f1" in headers and server returns status code 304.
And second question: Will browser cache resource and request it with ETag if Cache-control is set to no-cache?

For first part of question - It is up to your browser (its implementation and configuration) if the response will be cached and when will be revalidated. The only (standardized) difference between browser behaviour with validation headers and behaviour without validation headers is that former one can reduce traffic with server using validation.
Second question: Yes. Browser will cache resource but every time you open the page browser will ask origin server if resource was not modified. If not modified server will respond 304 and browser will display cached content. Otherwise server will send new content.

My guess would be ETag can serve as cache-control: no-cache.

Related

How can I force browsers use expire (rather than etags/modification time)

I have a server serving static files with an expire of 1 year but my browsers still get the file and receive a 304 - not modified. I want to prevent the browser from even attempting the connection. I realize that that happens in several different setup (Ubuntu Linux) with Chrome and Firefox.
My test is as follows:
$ wget -S -O /dev/null http://trepalchi.it/static/img/logo-trepalchi-black.svg
--2016-03-14 19:56:14-- http://trepalchi.it/static/img/logo-trepalchi-black.svg
Risoluzione di trepalchi.it (trepalchi.it)... 213.136.85.40
Connessione a trepalchi.it (trepalchi.it)|213.136.85.40|:80... connesso.
Richiesta HTTP inviata, in attesa di risposta...
HTTP/1.1 200 OK
Server: nginx/1.2.1
Date: Mon, 14 Mar 2016 18:55:29 GMT
Content-Type: image/svg+xml
Content-Length: 25081
Last-Modified: Sun, 13 Mar 2016 23:03:53 GMT
Connection: keep-alive
Expires: Tue, 14 Mar 2017 18:55:29 GMT
Cache-Control: max-age=31536000
Cache-Control: public
Accept-Ranges: bytes
Lunghezza: 25081 (24K) [image/svg+xml]
Salvataggio in: "/dev/null"
100%[==================================================================================================================================================================>] 25.081 --.-K/s in 0,07s
2016-03-14 19:56:14 (328 KB/s) - "/dev/null" salvato [25081/25081]
That shows correctly providing expires and cache control (via nginx).
If I go to the browser and enable cache and open diagnostic tools, the first hit I notice a 200 return code, then I refresh the page (Control-r) and find a connection with 304 - not modified return code.
Inspecting firefox cache (about:cache) I found it with correct expire and clicking on the link in that page I was able to see it w/o hitting the remote server.
I also tested pages where the images are loaded from image tags (as opposed as directly called as in the example above).
All the letterature I read state that with such an expire the browser should not even try a connection. What's wrong? RFC 2616 states:
HTTP caching works best when caches can entirely avoid making requests
to the origin server. The primary mechanism for avoiding requests is
for an origin server to provide an explicit expiration time in the
future, indicating that a response MAY be used to satisfy subsequent
requests. In other words, a cache can return a fresh response without
first contacting the server.
Note another question addresses the problem of how 304 is generated, I just want to prevent the connection to be made
Sandro
Thanks

Does if-no-match need to be set programmatically in ajax request, if server sends Etag

My question is pretty simple. Although while searching over, I have not found a simple satisfying answer.
I am using Jquery ajax request to get the data from a server. Server
hosts a rest API that sets the Etag and Cach-control headers to the GET requests. The Server also sets CORS headers to allow the Etag.
The client of the Api is a browser web app. I am using Ajax request to call the Api. Here are the response headers from server after a simple GET request:
Status Code: 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-transform, max-age=86400
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: application/json
Date: Sun, 30 Aug 2015 13:23:41 GMT
Etag: "-783704964"
Keep-Alive: timeout=15, max=99
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
Vary: Accept-Encoding
access-control-allow-headers: X-Requested-With, Content-Type, Etag,Authorization
access-control-allow-methods: GET, POST, DELETE, PUT
All I want to know is:
Do I need to manually collect the Etag from response headers sent from the server and attach an if-no-match header to ajax request?OR the Browser sends it by-default in a conditional get request when it has an 'Etag'
I have done debugging over the network console in the browser and It
seems the browser is doing the conditional GET automatically and
sets the if-no-match header.
if it is right, Suppose, I created a new resource, and then I called the get request. It gives me the past cached data for the first time. But when I reload the page, It gives the updated one. So I am confused that, If the dataset on the server-side has changed and it sends a different Etag, Why doesn't the browser get an updated data set from the server unless I have to reload
Also in case of pagination. Suppose I have a URL /users?next=0. next is a query param where the value for the next changes for every new request. Since each response will get its own 'Etag'. Will the browser store the 'Etag' based on request or it just stores the lastest Etag of the previous get request, irrespective of the URL.
Well, I have somehow figured out the solution myself:
The browser sends the if-no-match header itself when it sees url had the e-tag header on a previous request. Browser saves the e-tag with respect to that URL, so it does not matter how many requests with different URLs happen.
Also, a trick to force the browser to fetch a conditional-get to check the e-tag:
Set the max-age header to the lowest (for me 60s works great)
once the cache expires, thebrowser will send a conditional-get to check if the expired cached resource is valid. If the if-no-match header matches with e-tag. The server sends the response back with 304: Not-Modified header. This means the expired cached resource is valid and can be used.

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.

How do I know if image from my site is getting cached by proxy servers?

The following is a http response header from a image on our company's website.
HTTP/1.1 200 OK
Content-Type: image/png
Last-Modified: Thu, 03 Dec 2009 15:51:57 GMT
Accept-Ranges: bytes
ETag: "1e61e38a3074ca1:0"
Date: Wed, 06 Jan 2010 22:06:23 GMT
Content-Length: 9140
Is there anyway to know if this image is publicly cacheable in some proxy server? The RFC definition seems to be ambiguous http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 and http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.4.
Run RED on your URL and it'll tell you whether the response is cacheable, among other information.
The headers you show appear to be cacheable.
If you would like to control the caching behavior of correctly configured proxies and web browsers, you might investigate using the Cache-Control and Expires headers to gain additional control.
Here is a webpage I had bookmarked that has one person's opinion of how to intepret the specifications you list (plus some other ones):
http://www.web-caching.com/mnot_tutorial/how.html
If you need to guarantee that someone sees a completely new image each time (even with misconfigured devices between you and them), you may want to consider using a randomized or GUID value as part of the URL.
Here is a tutorial on setting headers for proxy caching. Be sure to read the part about setting cookies!

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