diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt index 7affe9519..11079b74d 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.kt @@ -25,6 +25,7 @@ import androidx.lifecycle.coroutineScope import coil.ImageLoaderFactory import coil.decode.ImageDecoderDecoder import coil.util.DebugLogger +import com.google.net.cronet.okhttptransport.RedirectStrategy.withoutRedirects import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhTagDatabase import com.hippo.ehviewer.client.data.GalleryDetail @@ -154,7 +155,7 @@ class EhApplication : Application(), ImageLoaderFactory { } companion object { - val nonCacheOkHttpClient by lazy { + private val baseOkHttpClient by lazy { httpClient { cookieJar(EhCookieStore) if (isAtLeastQ) { @@ -164,6 +165,11 @@ class EhApplication : Application(), ImageLoaderFactory { if (Settings.bypassCloudflare) { addInterceptor(CloudflareInterceptor(appCtx)) } + } + } + + val nonCacheOkHttpClient by lazy { + httpClient(baseOkHttpClient) { // TODO: Rewrite CronetInterceptor to use android.net.http.HttpEngine and make it Android 14 only when released if (isCronetSupported) { addInterceptor(EhCookieStore) @@ -172,6 +178,18 @@ class EhApplication : Application(), ImageLoaderFactory { } } + val noRedirectOkHttpClient by lazy { + httpClient(baseOkHttpClient) { + followRedirects(false) + if (isCronetSupported) { + addInterceptor(EhCookieStore) + cronet(cronetHttpClient) { + setRedirectStrategy(withoutRedirects()) + } + } + } + } + // Never use this okhttp client to download large blobs!!! val okHttpClient by lazy { httpClient(nonCacheOkHttpClient) { diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt index 570127a5a..7ffee7760 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt @@ -22,6 +22,8 @@ import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.data.GalleryInfo import com.hippo.ehviewer.client.exception.EhException +import com.hippo.ehviewer.client.exception.InsufficientFundsException +import com.hippo.ehviewer.client.exception.NotLoggedInException import com.hippo.ehviewer.client.exception.ParseException import com.hippo.ehviewer.client.parser.ArchiveParser import com.hippo.ehviewer.client.parser.EventPaneParser @@ -134,6 +136,17 @@ private suspend inline fun Request.executeAndParsingWith(block: suspend Stri } object EhEngine { + suspend fun getOriginalImageUrl(url: String, referer: String?): String { + Log.d(TAG, url) + return ehRequest(url, referer).executeNoRedirect { + header("Location")?.apply { + if (contains("bounce_login")) { + throw NotLoggedInException() + } + } ?: throw InsufficientFundsException() + } + } + suspend fun getTorrentList(url: String, gid: Long, token: String?): TorrentResult { val referer = EhUrl.getGalleryDetailUrl(gid, token) return ehRequest(url, referer).executeAndParsingWith(TorrentParser::parse) diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt b/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt index 7cbc43c82..45bf9d4c7 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt @@ -16,6 +16,7 @@ package com.hippo.ehviewer.client import android.util.Log +import com.hippo.ehviewer.EhApplication.Companion.noRedirectOkHttpClient import com.hippo.ehviewer.EhApplication.Companion.nonCacheOkHttpClient import com.hippo.ehviewer.EhApplication.Companion.okHttpClient import kotlinx.coroutines.coroutineScope @@ -105,6 +106,7 @@ suspend inline fun Call.usingCancellable(crossinline block: suspend Response suspend inline fun Request.execute(block: Response.() -> R) = okHttpClient.newCall(this).executeAsync().use(block) suspend inline fun Request.executeNonCache(crossinline block: suspend Response.() -> R) = nonCacheOkHttpClient.newCall(this).usingCancellable(block) +suspend inline fun Request.executeNoRedirect(block: Response.() -> R) = noRedirectOkHttpClient.newCall(this).executeAsync().use(block) suspend inline fun Request.executeAndParseAs() = execute { parseAs() } diff --git a/app/src/main/java/com/hippo/ehviewer/client/exception/NotLoggedInException.kt b/app/src/main/java/com/hippo/ehviewer/client/exception/NotLoggedInException.kt new file mode 100644 index 000000000..36b9237d3 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/exception/NotLoggedInException.kt @@ -0,0 +1,5 @@ +package com.hippo.ehviewer.client.exception + +import com.hippo.ehviewer.R + +class NotLoggedInException : EhException(R.string.sign_in_first) diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/ForumsParser.kt b/app/src/main/java/com/hippo/ehviewer/client/parser/ForumsParser.kt index 5373bd8ca..584cf6056 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/parser/ForumsParser.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/ForumsParser.kt @@ -16,7 +16,7 @@ package com.hippo.ehviewer.client.parser import com.hippo.ehviewer.client.EhUrl -import com.hippo.ehviewer.client.exception.EhException +import com.hippo.ehviewer.client.exception.NotLoggedInException import com.hippo.ehviewer.util.ExceptionUtils import org.jsoup.Jsoup @@ -29,7 +29,7 @@ object ForumsParser { child.attr("href") }.getOrElse { ExceptionUtils.throwIfFatal(it) - throw EhException("Not logged in") + throw NotLoggedInException() } } } diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.kt b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.kt index f6af6c540..0898dc611 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.kt +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.kt @@ -29,6 +29,7 @@ import com.hippo.ehviewer.client.EhUrl.getGalleryMultiPageViewerUrl import com.hippo.ehviewer.client.EhUrl.referer import com.hippo.ehviewer.client.data.GalleryInfo import com.hippo.ehviewer.client.ehRequest +import com.hippo.ehviewer.client.exception.EhException import com.hippo.ehviewer.client.exception.ParseException import com.hippo.ehviewer.client.execute import com.hippo.ehviewer.client.parser.GalleryDetailParser.parsePages @@ -722,8 +723,14 @@ class SpiderQueen private constructor(val galleryInfo: GalleryInfo) : CoroutineS val referer: String? if ((Settings.downloadOriginImage || orgImg) && !originImageUrl.isNullOrBlank()) { - targetImageUrl = originImageUrl - referer = EhUrl.getPageUrl(mSpiderInfo.gid, index, pToken) + val pageUrl = EhUrl.getPageUrl(mSpiderInfo.gid, index, pToken) + targetImageUrl = runSuspendCatching { + EhEngine.getOriginalImageUrl(originImageUrl!!, pageUrl) + }.getOrElse { + error = ExceptionUtils.getReadableString(it) + if (it is EhException) break else continue + } + referer = EhUrl.referer } else { targetImageUrl = imageUrl referer = null diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7d8696f12..9a7bf3a1f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -346,7 +346,7 @@ 预载图片 向后预载 %s 张图片 下载原图 - 这很危险!勾选此项会导致下载配额迅速流失 + 警告!可能需要 GP 允许媒体扫描 请避免他人翻看你的图库应用 大多数图库应用将不会显示下载目录中的图片 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ed79087b4..03d592bc1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -393,7 +393,7 @@ Preload image Preload next %s image Download original image - It is dangerous! You may get 509 error + Caution! May require GP Restore download items Restore all download items in download location Not found download items to restore