Prevent okhttp from caching covers and chapter images (#7967)

This commit is contained in:
stevenyomi 2022-09-12 06:00:07 +08:00 committed by GitHub
parent 935c8e7d82
commit 52fa28c16a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 31 deletions

View File

@ -11,7 +11,6 @@ import eu.kanade.domain.manga.model.Manga as DomainManga
/** /**
* Class used to create cover cache. * Class used to create cover cache.
* It is used to store the covers of the library. * It is used to store the covers of the library.
* Makes use of Glide (which can avoid repeating requests) to download covers.
* Names of files are created with the md5 of the thumbnail URL. * Names of files are created with the md5 of the thumbnail URL.
* *
* @param context the application context. * @param context the application context.

View File

@ -14,6 +14,7 @@ import eu.kanade.domain.manga.model.MangaCover
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher.Companion.USE_CUSTOM_COVER import eu.kanade.tachiyomi.data.coil.MangaCoverFetcher.Companion.USE_CUSTOM_COVER
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.network.CACHE_CONTROL_NO_STORE
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
@ -23,14 +24,13 @@ import okhttp3.CacheControl
import okhttp3.Call import okhttp3.Call
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.closeQuietly import okhttp3.internal.http.HTTP_NOT_MODIFIED
import okio.Path.Companion.toOkioPath import okio.Path.Companion.toOkioPath
import okio.Source import okio.Source
import okio.buffer import okio.buffer
import okio.sink import okio.sink
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.net.HttpURLConnection
import eu.kanade.domain.manga.model.Manga as DomainManga import eu.kanade.domain.manga.model.Manga as DomainManga
/** /**
@ -125,7 +125,7 @@ class MangaCoverFetcher(
} }
// Read from disk cache // Read from disk cache
snapshot = writeToDiskCache(snapshot, response) snapshot = writeToDiskCache(response)
if (snapshot != null) { if (snapshot != null) {
return SourceResult( return SourceResult(
source = snapshot.toImageSource(), source = snapshot.toImageSource(),
@ -141,11 +141,11 @@ class MangaCoverFetcher(
dataSource = if (response.cacheResponse != null) DataSource.DISK else DataSource.NETWORK, dataSource = if (response.cacheResponse != null) DataSource.DISK else DataSource.NETWORK,
) )
} catch (e: Exception) { } catch (e: Exception) {
responseBody.closeQuietly() responseBody.close()
throw e throw e
} }
} catch (e: Exception) { } catch (e: Exception) {
snapshot?.closeQuietly() snapshot?.close()
throw e throw e
} }
} }
@ -153,8 +153,8 @@ class MangaCoverFetcher(
private suspend fun executeNetworkRequest(): Response { private suspend fun executeNetworkRequest(): Response {
val client = sourceLazy.value?.client ?: callFactoryLazy.value val client = sourceLazy.value?.client ?: callFactoryLazy.value
val response = client.newCall(newRequest()).await() val response = client.newCall(newRequest()).await()
if (!response.isSuccessful && response.code != HttpURLConnection.HTTP_NOT_MODIFIED) { if (!response.isSuccessful && response.code != HTTP_NOT_MODIFIED) {
response.body?.closeQuietly() response.close()
throw HttpException(response) throw HttpException(response)
} }
return response return response
@ -167,18 +167,12 @@ class MangaCoverFetcher(
// Support attaching custom data to the network request. // Support attaching custom data to the network request.
.tag(Parameters::class.java, options.parameters) .tag(Parameters::class.java, options.parameters)
val diskRead = options.diskCachePolicy.readEnabled
val networkRead = options.networkCachePolicy.readEnabled
when { when {
!networkRead && diskRead -> { options.networkCachePolicy.readEnabled -> {
request.cacheControl(CacheControl.FORCE_CACHE) // don't take up okhttp cache
request.cacheControl(CACHE_CONTROL_NO_STORE)
} }
networkRead && !diskRead -> if (options.diskCachePolicy.writeEnabled) { else -> {
request.cacheControl(CacheControl.FORCE_NETWORK)
} else {
request.cacheControl(CACHE_CONTROL_FORCE_NETWORK_NO_CACHE)
}
!networkRead && !diskRead -> {
// This causes the request to fail with a 504 Unsatisfiable Request. // This causes the request to fail with a 504 Unsatisfiable Request.
request.cacheControl(CACHE_CONTROL_NO_NETWORK_NO_CACHE) request.cacheControl(CACHE_CONTROL_NO_NETWORK_NO_CACHE)
} }
@ -234,18 +228,9 @@ class MangaCoverFetcher(
} }
private fun writeToDiskCache( private fun writeToDiskCache(
snapshot: DiskCache.Snapshot?,
response: Response, response: Response,
): DiskCache.Snapshot? { ): DiskCache.Snapshot? {
if (!options.diskCachePolicy.writeEnabled) { val editor = diskCacheLazy.value.edit(diskCacheKey) ?: return null
snapshot?.closeQuietly()
return null
}
val editor = if (snapshot != null) {
snapshot.closeAndEdit()
} else {
diskCacheLazy.value.edit(diskCacheKey)
} ?: return null
try { try {
diskCacheLazy.value.fileSystem.write(editor.data) { diskCacheLazy.value.fileSystem.write(editor.data) {
response.body!!.source().readAll(this) response.body!!.source().readAll(this)
@ -349,7 +334,6 @@ class MangaCoverFetcher(
companion object { companion object {
const val USE_CUSTOM_COVER = "use_custom_cover" const val USE_CUSTOM_COVER = "use_custom_cover"
private val CACHE_CONTROL_FORCE_NETWORK_NO_CACHE = CacheControl.Builder().noCache().noStore().build()
private val CACHE_CONTROL_NO_NETWORK_NO_CACHE = CacheControl.Builder().noCache().onlyIfCached().build() private val CACHE_CONTROL_NO_NETWORK_NO_CACHE = CacheControl.Builder().noCache().onlyIfCached().build()
} }
} }

View File

@ -10,6 +10,7 @@ import java.util.concurrent.TimeUnit.MINUTES
private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build() private val DEFAULT_CACHE_CONTROL = CacheControl.Builder().maxAge(10, MINUTES).build()
private val DEFAULT_HEADERS = Headers.Builder().build() private val DEFAULT_HEADERS = Headers.Builder().build()
private val DEFAULT_BODY: RequestBody = FormBody.Builder().build() private val DEFAULT_BODY: RequestBody = FormBody.Builder().build()
internal val CACHE_CONTROL_NO_STORE = CacheControl.Builder().noStore().build()
fun GET( fun GET(
url: String, url: String,

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online package eu.kanade.tachiyomi.source.online
import eu.kanade.tachiyomi.network.CACHE_CONTROL_NO_STORE
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
@ -15,7 +16,6 @@ import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.net.URI import java.net.URI
import java.net.URISyntaxException import java.net.URISyntaxException
@ -301,7 +301,11 @@ abstract class HttpSource : CatalogueSource {
* @param page the page whose source image has to be downloaded. * @param page the page whose source image has to be downloaded.
*/ */
fun fetchImage(page: Page): Observable<Response> { fun fetchImage(page: Page): Observable<Response> {
return client.newCallWithProgress(imageRequest(page), page) val request = imageRequest(page).newBuilder()
// images will be cached or saved manually, so don't take up network cache
.cacheControl(CACHE_CONTROL_NO_STORE)
.build()
return client.newCallWithProgress(request, page)
.asObservableSuccess() .asObservableSuccess()
} }