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)
@@ -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
@@ -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
@@ -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]