in ktor-client/ktor-client-core/common/src/io/ktor/client/features/cache/HttpCache.kt [67:109]
override fun install(feature: HttpCache, scope: HttpClient) {
val CachePhase = PipelinePhase("Cache")
scope.sendPipeline.insertPhaseAfter(HttpSendPipeline.State, CachePhase)
scope.sendPipeline.intercept(CachePhase) { content ->
if (content !is OutgoingContent.NoContent) return@intercept
if (context.method != HttpMethod.Get || !context.url.protocol.canStore()) return@intercept
val cache = feature.findResponse(context, content) ?: return@intercept
if (!cache.shouldValidate()) {
finish()
proceedWith(cache.produceResponse().call)
return@intercept
}
cache.responseHeaders[HttpHeaders.ETag]?.let { etag ->
context.header(HttpHeaders.IfNoneMatch, etag)
}
cache.responseHeaders[HttpHeaders.LastModified]?.let {
context.header(HttpHeaders.IfModifiedSince, it)
}
}
scope.receivePipeline.intercept(HttpReceivePipeline.State) { response ->
if (context.request.method != HttpMethod.Get) return@intercept
if (response.status.isSuccess()) {
val reusableResponse = feature.cacheResponse(response)
proceedWith(reusableResponse)
return@intercept
}
if (response.status == HttpStatusCode.NotModified) {
response.complete()
val responseFromCache = feature.findAndRefresh(response)
?: throw InvalidCacheStateException(context.request.url)
proceedWith(responseFromCache)
}
}
}