From ae22f448a89280ab454cb969979f99ebbcc37e38 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:01:16 +0800 Subject: [PATCH] Revert to use OkHttp as fallback engine This partially reverts commit 7b67210876975d5b63559204c476ea8b50d55e00 Reason for revert: `setApplicationProtocols` used by Apache 5 HC is not available until API 29. --- README.md | 3 +- app/build.gradle.kts | 4 +++ app/proguard-rules.pro | 8 ------ .../com/hippo/ehviewer/EhApplication.kt | 16 +++++++++-- .../ehviewer/ui/settings/AdvancedScreen.kt | 4 +-- .../UncaughtExceptionInterceptor.kt | 28 +++++++++++++++++++ docs/README/zh-cn.md | 3 +- docs/README/zh-tw.md | 3 +- gradle/libs.versions.toml | 8 ++++-- 9 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 app/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt diff --git a/README.md b/README.md index d53f7921c..095570a4f 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ and [Dynamic Color](https://m3.material.io/styles/color/dynamic-color/overview) \* Archives and GIFs are not supported -** Fall back to Apache5 on devices that don't support [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) +** Fall back to OkHttp on devices that don't support [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) Get it on GitHub @@ -95,6 +95,7 @@ Here is the libraries - [Kotlin & KotlinX](https://kotlinlang.org/) - [MDC-Android](https://github.com/material-components/material-components-android) - [Material Icons](https://github.com/google/material-design-icons) +- [OkHttp](https://square.github.io/okhttp/) - [Ktor](https://ktor.io/) - [Coil](https://coil-kt.github.io/coil/) - [Compose Destinations](https://composedestinations.rafaelcosta.xyz/) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index de35851e2..1f42df94d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -236,6 +236,10 @@ dependencies { implementation(libs.bundles.splitties) + // https://square.github.io/okhttp/changelogs/changelog/ + implementation(platform(libs.okhttp.bom)) + implementation(libs.bundles.okhttp) + implementation(libs.okio.jvm) implementation(libs.diff) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 4acb4c7da..bb0768de0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -14,14 +14,6 @@ # Ktor logger -dontwarn org.slf4j.impl.StaticLoggerBinder -# Apache5 Http Client --dontwarn org.ietf.jgss.GSSContext --dontwarn org.ietf.jgss.GSSCredential --dontwarn org.ietf.jgss.GSSException --dontwarn org.ietf.jgss.GSSManager --dontwarn org.ietf.jgss.GSSName --dontwarn org.ietf.jgss.Oid - -dontwarn org.conscrypt.Conscrypt -allowaccessmodification diff --git a/app/src/main/kotlin/com/hippo/ehviewer/EhApplication.kt b/app/src/main/kotlin/com/hippo/ehviewer/EhApplication.kt index 962e345af..385541b8a 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/EhApplication.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/EhApplication.kt @@ -51,15 +51,19 @@ import com.hippo.ehviewer.util.FavouriteStatusRouter import com.hippo.ehviewer.util.FileUtils import com.hippo.ehviewer.util.ReadableTime import com.hippo.ehviewer.util.isAtLeastP +import com.hippo.ehviewer.util.isAtLeastQ import com.hippo.ehviewer.util.isAtLeastS import com.hippo.ehviewer.util.isCronetAvailable +import eu.kanade.tachiyomi.network.interceptor.UncaughtExceptionInterceptor import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.system.logcat import io.ktor.client.HttpClient -import io.ktor.client.engine.apache5.Apache5 +import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.plugins.cookies.HttpCookies import kotlinx.coroutines.launch +import okhttp3.AsyncDns +import okhttp3.android.AndroidAsyncDns import okio.Path.Companion.toOkioPath import splitties.arch.room.roomDb import splitties.init.appCtx @@ -178,7 +182,15 @@ class EhApplication : Application(), SingletonImageLoader.Factory { } } } else { - HttpClient(Apache5) { + HttpClient(OkHttp) { + engine { + config { + if (isAtLeastQ) { + dns(AsyncDns.toDns(AndroidAsyncDns.IPv4, AndroidAsyncDns.IPv6)) + } + addInterceptor(UncaughtExceptionInterceptor()) + } + } install(HttpCookies) { storage = EhCookieStore } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt index 0e4a8e6b4..f05b3119b 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/AdvancedScreen.kt @@ -142,7 +142,7 @@ fun AdvancedScreen(navigator: DestinationsNavigator) { var enableCronet by Settings::enableCronet.observed Preference( title = stringResource(id = R.string.settings_advanced_http_engine), - summary = if (enableCronet) "Cronet" else "Apache 5", + summary = if (enableCronet) "Cronet" else "OkHttp", ) { coroutineScope.launch { dialogState.awaitPermissionOrCancel( @@ -156,7 +156,7 @@ fun AdvancedScreen(navigator: DestinationsNavigator) { onClick = { enableCronet = false }, shape = SegmentedButtonDefaults.itemShape(index = 0, count = 2), ) { - Text("Apache 5") + Text("OkHttp") } SegmentedButton( selected = enableCronet, diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt new file mode 100644 index 000000000..a746ae773 --- /dev/null +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt @@ -0,0 +1,28 @@ +package eu.kanade.tachiyomi.network.interceptor + +import java.io.IOException +import okhttp3.Interceptor +import okhttp3.Response + +/** + * Catches any uncaught exceptions from later in the chain and rethrows as a non-fatal + * IOException to avoid catastrophic failure. + * + * This should be the first interceptor in the client. + * + * See [Interceptor](https://square.github.io/okhttp/5.x/okhttp/okhttp3/-interceptor/index.html) + */ +class UncaughtExceptionInterceptor : Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + return try { + chain.proceed(chain.request()) + } catch (e: Exception) { + if (e is IOException) { + throw e + } else { + throw IOException(e) + } + } + } +} diff --git a/docs/README/zh-cn.md b/docs/README/zh-cn.md index 26d9bcb09..c44876260 100644 --- a/docs/README/zh-cn.md +++ b/docs/README/zh-cn.md @@ -74,7 +74,7 @@ \* 不支持压缩包和 GIF -** 在不支持 [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) 的设备上回退到 Apache5 +** 在不支持 [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) 的设备上回退到 OkHttp Get it on GitHub @@ -94,6 +94,7 @@ - [Kotlin & KotlinX](https://kotlinlang.org/) - [MDC-Android](https://github.com/material-components/material-components-android) - [Material Icons](https://github.com/google/material-design-icons) +- [OkHttp](https://square.github.io/okhttp/) - [Ktor](https://ktor.io/) - [Coil](https://coil-kt.github.io/coil/) - [Compose Destinations](https://composedestinations.rafaelcosta.xyz/) diff --git a/docs/README/zh-tw.md b/docs/README/zh-tw.md index 54f33eeee..cdc7f37de 100644 --- a/docs/README/zh-tw.md +++ b/docs/README/zh-tw.md @@ -74,7 +74,7 @@ \* 不支援壓縮包和 GIF -** 在不支援 [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) 的裝置上回退到 Apache5 +** 在不支援 [HttpEngine](https://developer.android.com/reference/android/net/http/HttpEngine) 的裝置上回退到 OkHttp Get it on GitHub @@ -94,6 +94,7 @@ - [Kotlin & KotlinX](https://kotlinlang.org/) - [MDC-Android](https://github.com/material-components/material-components-android) - [Material Icons](https://github.com/google/material-design-icons) +- [OkHttp](https://square.github.io/okhttp/) - [Ktor](https://ktor.io/) - [Coil](https://coil-kt.github.io/coil/) - [Compose Destinations](https://composedestinations.rafaelcosta.xyz/) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 30c4b099b..e619d984b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,6 +28,7 @@ kotlinx-serialization = "1.6.2" ksp = "2.0.0-Beta1-1.0.15" ktlint = "1.0.1" ktor = "3.0.0-beta-1" +okhttp3 = "5.0.0-alpha.11" okio = "3.7.0" splitties = "3.0.0" @@ -95,10 +96,12 @@ kotlinx-serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-seri # For renovate ktlint = { module = "com.pinterest:ktlint", version.ref = "ktlint" } -ktor-client-apache5 = { module = "io.ktor:ktor-client-apache5", version.ref = "ktor" } +ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } material = { module = "com.google.android.material:material", version.ref = "google-android-material" } +okhttp-android = { module = "com.squareup.okhttp3:okhttp-android" } +okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp3" } okio-jvm = { module = "com.squareup.okio:okio-jvm", version.ref = "okio" } photoview = "com.github.chrisbanes:PhotoView:2.3.0" @@ -118,7 +121,8 @@ coil = ["coil-compose", "coil-gif"] compose = ["compose-foundation", "compose-material-icons-extended", "compose-material3", "compose-material3-windowsizeclass", "compose-ui-util"] cronet = ["cronet-api", "cronet-gms"] kotlinx-serialization = ["kotlinx-serialization-cbor", "kotlinx-serialization-json", "kotlinx-serialization-json-okio"] -ktor = ["ktor-client-apache5"] +ktor = ["ktor-client-okhttp"] +okhttp = ["okhttp-android"] splitties = ["splitties-appctx", "splitties-arch-room", "splitties-preferences", "splitties-systemservices"] [plugins]