okhttphttp-caching

How to influence OkHttp cache usage?


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:


Solution

  • It needs to be a networkInterceptor, but it definitely works.

    Try .header("Cache-Control", "public, max-age=1000"), which should cache for 15 minutes.

    See https://stackoverflow.com/a/23503804/1542667