diff --git a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt index 9766d6a2e..5f1cc4487 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/Settings.kt @@ -9,10 +9,10 @@ import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.remember +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.preferences.DataStorePreferences import com.ehviewer.core.preferences.PrefDelegate import com.ehviewer.core.preferences.edit -import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.data.FavListUrlBuilder import com.hippo.ehviewer.download.DownloadsFilterMode import com.hippo.ehviewer.download.SortMode diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt index 91a0136d7..980563466 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhEngine.kt @@ -24,6 +24,7 @@ import arrow.fx.coroutines.parZip import com.ehviewer.core.i18n.R import com.ehviewer.core.model.BaseGalleryInfo import com.ehviewer.core.model.GalleryInfo +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.util.logcat import com.hippo.ehviewer.EhDB import com.hippo.ehviewer.Settings diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhUtils.kt b/app/src/main/kotlin/com/hippo/ehviewer/client/EhUtils.kt index 58253912b..084ddca8d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhUtils.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/client/EhUtils.kt @@ -29,6 +29,7 @@ import androidx.core.net.toUri import arrow.core.memoize import com.ehviewer.core.model.GalleryDetail import com.ehviewer.core.model.GalleryInfo +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.util.withUIContext import com.hippo.ehviewer.Settings import com.hippo.ehviewer.client.parser.Archive diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ktor/Common.kt b/app/src/main/kotlin/com/hippo/ehviewer/ktor/Common.kt index b0b342922..613b0125d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ktor/Common.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ktor/Common.kt @@ -1,8 +1,8 @@ package com.hippo.ehviewer.ktor +import com.ehviewer.core.network.EhCookieStore import com.hippo.ehviewer.BuildConfig import com.hippo.ehviewer.Settings -import com.hippo.ehviewer.client.EhCookieStore import io.ktor.client.HttpClientConfig import io.ktor.client.engine.HttpClientEngineConfig import io.ktor.client.plugins.HttpTimeout diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/login/PostLogin.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/login/PostLogin.kt index 5bfd12217..3b83a5296 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/login/PostLogin.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/login/PostLogin.kt @@ -1,9 +1,9 @@ package com.hippo.ehviewer.ui.login import arrow.core.Either.Companion.catch +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.util.logcat import com.hippo.ehviewer.Settings -import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhEngine import com.hippo.ehviewer.client.EhUrl import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/login/WebViewSignInScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/login/WebViewSignInScreen.kt index f09dab611..d92238427 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/login/WebViewSignInScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/login/WebViewSignInScreen.kt @@ -6,10 +6,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Modifier +import com.ehviewer.core.network.EhCookieStore import com.google.accompanist.web.WebView import com.google.accompanist.web.rememberWebViewState import com.hippo.ehviewer.Settings -import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhUrl import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.ui.Screen diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt index 8425bd410..d3dcd3f0d 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt @@ -29,11 +29,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.fromHtml import com.ehviewer.core.i18n.R +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.util.isAtLeastT import com.ehviewer.core.util.launch import com.hippo.ehviewer.Settings import com.hippo.ehviewer.asMutableState -import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhTagDatabase import com.hippo.ehviewer.client.EhUtils import com.hippo.ehviewer.collectAsState diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/UConfigScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/UConfigScreen.kt index bb5a6d5ce..966dc5632 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/UConfigScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/UConfigScreen.kt @@ -16,11 +16,11 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.ehviewer.core.i18n.R +import com.ehviewer.core.network.EhCookieStore import com.ehviewer.core.util.launch import com.google.accompanist.web.WebView import com.google.accompanist.web.rememberWebViewNavigator import com.google.accompanist.web.rememberWebViewState -import com.hippo.ehviewer.client.EhCookieStore import com.hippo.ehviewer.client.EhUrl import com.hippo.ehviewer.ui.Screen import com.hippo.ehviewer.ui.main.NavigationIcon diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index 3269876ad..9929733c9 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -11,10 +11,13 @@ kotlin { api(projects.core.common) api(libs.androidx.datastore) api(libs.androidx.room.paging) + implementation(libs.ktor.client.core) } } androidMain { dependencies { + implementation(project.dependencies.platform(libs.okhttp.bom)) + implementation(libs.ktor.client.okhttp) } } } diff --git a/core/data/src/androidMain/kotlin/com/ehviewer/core/network/CookieManager.android.kt b/core/data/src/androidMain/kotlin/com/ehviewer/core/network/CookieManager.android.kt new file mode 100644 index 000000000..6d4616597 --- /dev/null +++ b/core/data/src/androidMain/kotlin/com/ehviewer/core/network/CookieManager.android.kt @@ -0,0 +1,16 @@ +package com.ehviewer.core.network + +import io.ktor.http.Cookie +import io.ktor.http.Url +import io.ktor.http.parseClientCookiesHeader +import io.ktor.http.renderSetCookieHeader + +class AndroidCookieManager : CookieManager { + private val manager = android.webkit.CookieManager.getInstance() + override fun getCookies(url: Url) = manager.getCookie(url.toString())?.let { parseClientCookiesHeader(it) } + override fun setCookie(url: Url, cookie: Cookie) = manager.setCookie(url.toString(), renderSetCookieHeader(cookie)) + override fun removeAllCookies() = manager.removeAllCookies(null) + override fun flush() = manager.flush() +} + +actual fun getCookieManager(): CookieManager = AndroidCookieManager() diff --git a/core/data/src/commonMain/kotlin/com/ehviewer/core/network/CookieManager.kt b/core/data/src/commonMain/kotlin/com/ehviewer/core/network/CookieManager.kt new file mode 100644 index 000000000..970c0db90 --- /dev/null +++ b/core/data/src/commonMain/kotlin/com/ehviewer/core/network/CookieManager.kt @@ -0,0 +1,13 @@ +package com.ehviewer.core.network + +import io.ktor.http.Cookie +import io.ktor.http.Url + +interface CookieManager { + fun getCookies(url: Url): Map? + fun setCookie(url: Url, cookie: Cookie) + fun removeAllCookies() + fun flush() +} + +expect fun getCookieManager(): CookieManager diff --git a/app/src/main/kotlin/com/hippo/ehviewer/client/EhCookieStore.kt b/core/data/src/commonMain/kotlin/com/ehviewer/core/network/EhCookieStore.kt similarity index 59% rename from app/src/main/kotlin/com/hippo/ehviewer/client/EhCookieStore.kt rename to core/data/src/commonMain/kotlin/com/ehviewer/core/network/EhCookieStore.kt index 7507378d0..e1851a0da 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/client/EhCookieStore.kt +++ b/core/data/src/commonMain/kotlin/com/ehviewer/core/network/EhCookieStore.kt @@ -1,17 +1,19 @@ -package com.hippo.ehviewer.client +package com.ehviewer.core.network -import android.webkit.CookieManager import io.ktor.client.plugins.cookies.CookiesStorage import io.ktor.http.Cookie +import io.ktor.http.URLBuilder +import io.ktor.http.URLProtocol import io.ktor.http.Url -import io.ktor.http.parseClientCookiesHeader -import io.ktor.http.renderSetCookieHeader object EhCookieStore : CookiesStorage { - private val manager = CookieManager.getInstance() - fun removeAllCookies() = manager.removeAllCookies(null) + private val manager = getCookieManager() + private val urlE = URLBuilder(URLProtocol.HTTPS, "e-hentai.org").build() + private val urlEx = URLBuilder(URLProtocol.HTTPS, "exhentai.org").build() - fun hasSignedIn(): Boolean = getCookies(EhUrl.HOST_E)?.run { + fun removeAllCookies() = manager.removeAllCookies() + + fun hasSignedIn(): Boolean = manager.getCookies(urlE)?.run { containsKey(KEY_IPB_MEMBER_ID) && containsKey(KEY_IPB_PASS_HASH) } == true @@ -29,18 +31,18 @@ object EhCookieStore : CookiesStorage { fun clearIgneous() { manager.setCookie( - EhUrl.HOST_EX, - renderSetCookieHeader(KEY_IGNEOUS, "", maxAge = 0, domain = EhUrl.DOMAIN_EX, path = "/"), + urlEx, + Cookie(KEY_IGNEOUS, "", maxAge = 0, domain = urlEx.host, path = "/"), ) } - fun getUserId() = getCookies(EhUrl.HOST_E)?.get(KEY_IPB_MEMBER_ID) + fun getUserId() = manager.getCookies(urlE)?.get(KEY_IPB_MEMBER_ID) - fun getHathPerks() = getCookies(EhUrl.HOST_E)?.get(KEY_HATH_PERKS)?.substringBefore('-') + fun getHathPerks() = manager.getCookies(urlE)?.get(KEY_HATH_PERKS)?.substringBefore('-') fun getIdentityCookies(): List> { - val eCookies = getCookies(EhUrl.HOST_E) - val exCookies = getCookies(EhUrl.HOST_EX) + val eCookies = manager.getCookies(urlE) + val exCookies = manager.getCookies(urlEx) val ipbMemberId = eCookies?.get(KEY_IPB_MEMBER_ID) val ipbPassHash = eCookies?.get(KEY_IPB_PASS_HASH) val igneous = exCookies?.get(KEY_IGNEOUS) @@ -51,24 +53,22 @@ object EhCookieStore : CookiesStorage { ) } - fun isCloudflareBypassed() = getCookies(EhUrl.HOST_E)?.containsKey("cf_clearance") == true + fun isCloudflareBypassed() = manager.getCookies(urlE)?.containsKey("cf_clearance") == true fun flush() = manager.flush() // See https://github.com/Ehviewer-Overhauled/Ehviewer/issues/873 override suspend fun addCookie(requestUrl: Url, cookie: Cookie) { if (cookie.name != KEY_UTMP_NAME) { - manager.setCookie(requestUrl.toString(), renderSetCookieHeader(cookie)) + manager.setCookie(requestUrl, cookie) } } override fun close() = Unit - private fun getCookies(url: String) = manager.getCookie(url)?.let { parseClientCookiesHeader(it) } - - fun load(url: Url): List { - val checkTips = EhUrl.DOMAIN_E in url.host - return getCookies(url.toString())?.mapTo(mutableListOf()) { + override suspend fun get(requestUrl: Url): List { + val checkTips = requestUrl.host == urlE.host + return manager.getCookies(requestUrl)?.mapTo(mutableListOf()) { Cookie(it.key, it.value) }?.apply { if (checkTips) { @@ -76,6 +76,4 @@ object EhCookieStore : CookiesStorage { } } ?: if (checkTips) listOf(sTipsCookie) else emptyList() } - - override suspend fun get(requestUrl: Url) = load(requestUrl) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4cef275a8..624039c0d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -100,6 +100,7 @@ kotlinx-io = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = " ktlint = "com.pinterest.ktlint:ktlint-cli:1.8.0" okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp" } +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } logcat = "com.squareup.logcat:logcat:0.4"