You can add a cache to an OkHttpClient
which will work according to the various cache-related HTTP header like cache-control
:
val okHttpClient =
OkHttpClient.Builder().apply {
cache(Cache(File("http_cache"), 50 * 1024 * 1024))
}.build()
There is a resource for which the server (which is not controlled by me) specifies cache-control: no-cache
in the response. But I want to cache it anyway, because I know that under certain circumstances it is safe to do so.
I thought I could intercept the response and set headers accordingly:
val okHttpClient =
OkHttpClient.Builder().apply {
cache(Cache(File("http_cache"), 50 * 1024 * 1024))
addInterceptor { chain ->
val response = chain.proceed(chain.request())
response
.newBuilder()
.header("cache-control", "max-age=1000") // Enable caching
.removeHeader("pragma") // Remove any headers that might conflict with caching
.removeHeader("expires") // ...
.removeHeader("x-cache") // ...
.build()
}
}.build()
Unfortunately, this does not work. Apparently, the caching decisions are made before the interceptor intercepts. Using addNetworkInterceptor()
instead of addInterceptor()
does not work either.
The opposite - disabling caching when the server allows it by setting cache-control: no-cache
- also does not work.
Edit:
Yuri's answer is correct. addNetworkInterceptor()
with .header("Cache-Control", "public, max-age=1000")
works, and .header("cache-control", "max-age=1000")
also works.
But when running my experiments, I had made some false assumptions. This is what I found out later:
no-cache
does not mean "don't cache". no-cache
allows caches to store a response, but requires them to revalidate it before reuse. If the sense of "don't cache" that you want is actually "don't store", then no-store
is the directive to use." (Source)It needs to be a networkInterceptor, but it definitely works.
Try .header("Cache-Control", "public, max-age=1000")
, which should cache for 15 minutes.