KMP EhCookieStore

This commit is contained in:
FooIbar committed 2025-11-29 15:08:32 +08:00
1 parent 99696b11db
commit 10f7b2a7a9
13 files changed
+61 -28

No files matched your search

@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+3
View File
@@ -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)
}
}
}
@@ -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()
@@ -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<String, String>?
fun setCookie(url: Url, cookie: Cookie)
fun removeAllCookies()
fun flush()
}
expect fun getCookieManager(): CookieManager
@@ -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<Pair<String, String?>> {
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<Cookie> {
val checkTips = EhUrl.DOMAIN_E in url.host
return getCookies(url.toString())?.mapTo(mutableListOf()) {
override suspend fun get(requestUrl: Url): List<Cookie> {
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)
}
+1
View File
@@ -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"