mrblrrd
mrblrrd

Reputation: 1529

okhttp cache-control no-cache processing strategy

I have a question about caching support in okhttp. This is a complex question, so I’ll break it into two parts.

1. no-cache processing strategy for request

I 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.

2. Cache-Control directive for using a cached response when there is no network

It 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.

Thank you in advance!

Upvotes: 1

Views: 327

Answers (2)

Jesse Wilson
Jesse Wilson

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

Jesse Wilson
Jesse Wilson

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

Related Questions