0

For the following image: https://upload.wikimedia.org/wikipedia/commons/7/79/2010-brown-bear.jpg

There isn't any cache-control header. And based on here even if you don't send anything then it will use its default value which is private. That being doesn't the URLSession need to perform a conditional request to make sure its still valid?

Is there anything in the headers that allows it to make such a conditional request? Because I don't see cache-control, max-age, Expires. The only things I see is are Last-Modified & Etag but again it needs to validate against the server or does not specifying anything make it cache indefinitely?! I've already read this answer, but doesn't discuss this scenario.

Yet it's being cached by the URLSession. (Because if I turn off internet, still it gets downloaded)

Only other thing I see is "Strict-Transport-Security": max-age=106384710.

Does that effect caching? I've already look here and don't believe it should. From what I the max-age for the HSTS key is there only to enforce it to be accessed from HTTPS for a certain period of time. Once the max-age is reached then access through HTTP is also possible.

These are all the headers that I'm getting back:

Date : Wed, 31 Oct 2018 14:15:33 GMT
Content-Length : 215104
Access-Control-Expose-Headers: Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish
Via : 1.1 varnish (Varnish/5.1), 1.1 varnish (Varnish/5.1)    
Age : 18581
Etag : 00e21950bf432476c91b811bb685b6af
Strict-Transport-Security : max-age=106384710; includeSubDomains; preload
Accept-Ranges : bytes
Content-Type : image/jpeg
Last-Modified : Fri, 04 Oct 2013 23:30:08 GMT
Access-Control-Allow-Origin : *
Timing-Allow-Origin : *
x-analytics : https=1;nocookies=1
x-object-meta-sha1base36 : 42tq5grg9rq1ydmqd4z5hmmqj6h2309
x-varnish : 60926196 48388489, 342256851 317476424
x-cache-status : hit-front
x-trans-id : tx08ed43bbcc1946269a9a3-005bd97070
x-timestamp : 1380929407.39127
x-cache : cp1076 hit/7, cp1090 hit/7
x-client-ip : 2001:558:1400:4e:171:2a98:fad6:2579

This question was asked because of this comment

mfaani
  • 33,269
  • 19
  • 164
  • 293

1 Answers1

3

doesn't the URLSession need to perform a conditional request to make sure its still valid?

The user-agent should be performing a conditional request, because of the

Etag: 00e21950bf432476c91b811bb685b6af

present. My desktop Chrome certainly does performs the conditional request (and gets back 304 Not Modified).

But it's free not to

But a user-agent is perfectly free to decide on it's own. It's perfectly free to look at:

Last-Modified: Fri, 04 Oct 2013 23:30:08 GMT

and decide that there resource is probably good for the next five minutes1. And if the network connection is down, its perfectly reasonable and correct to display the cached version instead. In fact, your browser would show you web-sites even while your dial-up 0.00336 Mbps dial-up modem was disconnected.

You wouldn't want your browser to show you nothing, when it knows full well it can show you something. It becomes even more useful when we're talking about poor internet connectivity not because of slow dialup and servers that go down, but of mobile computing, and metered data plans.

1I say 5 minutes, because in the early web, servers did not give cache hints. So browsers cached things without even being asked. And 5 minutes was a good number. And you used Ctrl+F5 (or was it Shift+F5, or was it Shift+Click, or was it Alt+Click) to force the browser to bypass the cache.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • That explains a lot. 1) _But a user-agent is perfectly free to decide on it's own_ ← from a developer's view. The user behavior is ambiguous. Are you saying different browsers, or operating systems will behave completely different? Like for same headers the behavior of Safari on Mac is different from Chrome on Mac or Safari on iPhone? 2) I also think if something hasn't changed since 5 years ago then the browser should act much smarter and cache it for another 2 years :) why just 5 minutes? – mfaani Nov 02 '18 at 16:10
  • _But it's free not to_ Any docs on that? I also looked into [here](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) but didn't find anything that would describe what you're saying – mfaani Nov 03 '18 at 02:09
  • 1
    What answer would you like? [If you check the RFC](https://tools.ietf.org/html/rfc7232#section-3) you'll note that nowhere are user agents ever even required to cache anything. They are only hints. If my program is calling an Http library, there *is* no caching (i'm not going to cache it, i simply request for the item and thats that). Nobody is required anywhere to ever honor any caching. The only time a user agent is required to do something is when the RFC says **`MUST`** - this is the special keyword. Other keywords are `SHOULD`, `MAY`, `SHOULD NOT`, `MUST NOT`. No user agent must cache. – Ian Boyd Nov 04 '18 at 21:37
  • which part of that page should I be looking at. Can you send me a phrase that I should look at? – mfaani Nov 04 '18 at 22:30
  • 1
    The problem is you're asking for a negative. Browers are allowed to ignore everything, because nothing in the RFC says they must do it. That's how it works: anything not required by the standard is left to the browser to do whatever it wants. If someone doesn't belive you, and they won't shut up about it until you bring them something they can read, then you can quote Ian Boyd from StackOverflow: `Browsers are permitted to ignore cache hints, including not refreshing a cached resource, even if the origin server's supplied Last Modified date says it's expired.` – Ian Boyd Nov 05 '18 at 03:23
  • Reminds me of the story from [Raymond Chen](https://learn.microsoft.com/en-us/previous-versions/technet-magazine/jj643252), where a customer just wanted some documentation, because they won't simply believe what they were being told. *"The customer is insistent on an official document so they can include it as part of their product documentation."* Making it official documentation, however, would defeat the whole purpose of having explicitly non-contractual behavior – Ian Boyd Nov 05 '18 at 03:25
  • :D You got me wrong Ian. That's not what I intended here. Just that I got kinda lost in the link you sent. When you click on the link it takes you to **recondition Header Fields** and I was scrolling *down*. But just right now seeing it again, I believe you wanted me to scroll **UP** and start reading from "SHOULD send"... I know you can't point to it. Because it doesn't exist. I just wanted to know to what part of the link I should read to just get a more meta data on the subject, hence I asked for a phrase... – mfaani Nov 05 '18 at 03:44
  • If you take a step back, and approach the entirety of the RFC as a *hint* for clients to cache content, then you can see the it. RFCs have a standard terminology of *must*, *should*, *may*, *should not*, *must not*. Nobody *has* to honor the directives; and quite often browsers won't. It would not surprise me if you said **URLSession** doesn't cache content, Microsoft's [**WinHttp**](https://docs.microsoft.com/en-us/windows/desktop/winhttp/about-winhttp) doesn't cache either - (that's your job: to store content *somewhere*, realize you cached it, perform conditional request, and get 304). – Ian Boyd Nov 05 '18 at 14:35
  • I never thought that directives *can* be ignored. Or never thought that I need to do a sanity check and see if its cached or not. I guess checking once in my entire development is enough ie if it works for certain headers then it will work in any app or setup. But I first need to check that combination of headers. – mfaani Nov 05 '18 at 14:58
  • Even better is that Microsoft's [`XmlHttpRequest` will use a cache, even if you add headers asking it not to](https://stackoverflow.com/questions/5235464/how-to-make-microsoft-xmlhttprequest-honor-cache-control-directive/5386957). To bypass the cache you have to use `ServerXmlHttpRequest`, but the downside there is that you have to do all caching yourself (i.e. unless do you the work: **nothing** is cached). – Ian Boyd Nov 05 '18 at 15:09