diff --git a/ktor-client/ktor-client-core/common/src/io/ktor/client/features/cache/HttpCacheEntry.kt b/ktor-client/ktor-client-core/common/src/io/ktor/client/features/cache/HttpCacheEntry.kt index 1c5139589..bedeffd53 100644 --- a/ktor-client/ktor-client-core/common/src/io/ktor/client/features/cache/HttpCacheEntry.kt +++ b/ktor-client/ktor-client-core/common/src/io/ktor/client/features/cache/HttpCacheEntry.kt @@ -87,9 +87,13 @@ internal fun HttpResponse.cacheExpires(): GMTDate { @KtorExperimentalAPI internal fun HttpCacheEntry.shouldValidate(): Boolean { val cacheControl = responseHeaders[HttpHeaders.CacheControl]?.let { parseHeaderValue(it) } ?: emptyList() - var result = GMTDate() > expires - result = result || CacheControl.MUST_REVALIDATE in cacheControl - result = result || CacheControl.NO_CACHE in cacheControl - - return result + val isStale = GMTDate() > expires + // must-revalidate; re-validate once STALE, and MUST NOT return a cached response once stale. + // This is how majority of clients implement the RFC + // OkHttp Implements this the same: https://github.com/square/okhttp/issues/4043#issuecomment-403679369 + // Disabled for now, as we don't currently return a cached object when there's a network failure; must-revalidate + // works the same as being stale on the request side. On response side, must-revalidate would not return a cached + // object if we are stale and couldn't refresh. + // isStale = isStale && CacheControl.MUST_REVALIDATE in cacheControl + return isStale || CacheControl.NO_CACHE in cacheControl }