Reputation: 1529
I have a question about caching support in okhttp. This is a complex question, so I’ll break it into two parts.
no-cache
processing strategy for requestI noticed that the request header Cache-Control: no-cache
, or as okhttp calls it CacheControl.FORCE_NETWORK
, does not result in cached response validation by passing the If-None-Match
or If-Modified-Since
headers etc., instead of this it always results in a network request and reading the response body.
Here's what RFC 9111 says:
5.2.1.4. no-cache
The no-cache request directive indicates that the client prefers a stored response not be used to satisfy the request without successful validation on the origin server.
The key for me here is “without successful validation”. That is, if the application, for instance, does not have a network, then it is prohibited to return the cached response, 'cause it cannot be validated. But if there is a network connection and the server returned 304
, then you can take the response from the cache.
There is also an informal description of the directives in this article (mentioned in Mozilla documentation)
A good use-case for no-cache would be almost any dynamic HTML page. Think of a news site’s homepage: it’s not realtime, nor does it contain any sensitive information, but ideally we’d like the page to always show the freshest content. We can use cache-control: no-cache to instruct the browser to check back with the server first, and if the server has nothing newer to offer (304), let’s reuse the cached version. In the event that the server did have some fresher content, it would respond as such (200) and send the newer file.
It says “if the server has nothing newer to offer (304), let’s reuse the cached version”.
Formally, the current implementation in okhttp does not contradict the RFC, but in my opinion it would be more efficient to take the response from the cache after successful validation in order to save traffic. It seems that this would be indistinguishable behavior from the current one, with the only difference being that the bytes would not be transferred over the network once again.
Cache-Control
value can be currently used for a traffic saving use case?Cache-Control
directive for using a cached response when there is no networkIt would be great to have a following strategy: try to validate the cached response on origin server, if the server responds that it's still valid (304), then use it, but if there is no network, then you can use the cached response. This would make it easier to implement offline support in mobile apps.
The most suitable directive for this purpose is stale-if-error
(RFC 5861 and the same article).
The stale-if-error Cache-Control extension indicates that when an error is encountered, a cached stale response MAY be used to satisfy the request, regardless of other freshness information.
stale-if-error
?Thank you in advance!
Upvotes: 1
Views: 327
Reputation: 40623
try to validate the cached response on origin server, if the server responds that it's still valid (304), then use it, but if there is no network, then you can use the cached response.
You could probably implement this feature as an application interceptor. Make a first call normally. If it throws, make a 2nd call with a Cache-Control header that’s very relaxed with respect to staleness. Throw in an only-if-cached parameter too!
We could probably implement this in OkHttp but I’d love for you to try it in the real world to see how it performs.
Upvotes: 1
Reputation: 40623
this it always results in a network request and reading the response body
I don’t believe this is the case. OkHttp will honor 304s and return the cached response body. You can see this by looking at the cacheResponse and networkResponse fields of a conditional hit.
Upvotes: 1