ani
ani copied to clipboard
自定义代理设置,Authorization 无效
问题描述
(我相信其实也没多少人用这个功能,所以 P2)
附一个 Patch: Move toClientProxyConfig and toHeader and modify ProxyAuthorization.toHeader()
移动了两个函数到正确位置。
ProxyAuthorization.toHeader() 不应该是 Basic $username:$password。
Subject: [PATCH] Move `toClientProxyConfig` and `toHeader` and modify `ProxyAuthorization.toHeader()`
---
Index: app/shared/app-data/src/commonMain/kotlin/data/models/preference/ProxyConfig.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/shared/app-data/src/commonMain/kotlin/data/models/preference/ProxyConfig.kt b/app/shared/app-data/src/commonMain/kotlin/data/models/preference/ProxyConfig.kt
--- a/app/shared/app-data/src/commonMain/kotlin/data/models/preference/ProxyConfig.kt (revision 18f6bfb0139a118ae08a76292671c24959a57b2d)
+++ b/app/shared/app-data/src/commonMain/kotlin/data/models/preference/ProxyConfig.kt (revision c4a26dd127f645d798d8c6b0faff92a91c356ce5)
@@ -9,9 +9,13 @@
package me.him188.ani.app.data.models.preference
+import io.ktor.util.encodeBase64
+import io.ktor.utils.io.charsets.Charsets
+import io.ktor.utils.io.core.toByteArray
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
+import me.him188.ani.utils.ktor.ClientProxyConfig
import me.him188.ani.utils.platform.annotations.SerializationOnly
/**
@@ -83,10 +87,21 @@
companion object {
val Default = ProxyConfig()
}
+
+ fun toClientProxyConfig(): ClientProxyConfig = ClientProxyConfig(
+ url = url,
+ authorization = authorization?.toHeader(),
+ )
}
@Serializable
data class ProxyAuthorization(
val username: String,
val password: String,
-)
+) {
+ fun toHeader(): String {
+ val base64 = "${username}:${password}".toByteArray(Charsets.UTF_8).encodeBase64()
+
+ return "Basic $base64"
+ }
+}
Index: app/shared/app-data/src/commonMain/kotlin/domain/foundation/HttpClientProvider.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/shared/app-data/src/commonMain/kotlin/domain/foundation/HttpClientProvider.kt b/app/shared/app-data/src/commonMain/kotlin/domain/foundation/HttpClientProvider.kt
--- a/app/shared/app-data/src/commonMain/kotlin/domain/foundation/HttpClientProvider.kt (revision 18f6bfb0139a118ae08a76292671c24959a57b2d)
+++ b/app/shared/app-data/src/commonMain/kotlin/domain/foundation/HttpClientProvider.kt (revision c4a26dd127f645d798d8c6b0faff92a91c356ce5)
@@ -27,7 +27,6 @@
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import me.him188.ani.app.data.models.preference.ProxyConfig
-import me.him188.ani.app.domain.media.fetch.toClientProxyConfig
import me.him188.ani.app.domain.settings.ProxyProvider
import me.him188.ani.utils.coroutines.childScope
import me.him188.ani.utils.ktor.ScopedHttpClient
Index: app/shared/app-data/src/commonMain/kotlin/domain/media/fetch/MediaSourceManager.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/shared/app-data/src/commonMain/kotlin/domain/media/fetch/MediaSourceManager.kt b/app/shared/app-data/src/commonMain/kotlin/domain/media/fetch/MediaSourceManager.kt
--- a/app/shared/app-data/src/commonMain/kotlin/domain/media/fetch/MediaSourceManager.kt (revision 18f6bfb0139a118ae08a76292671c24959a57b2d)
+++ b/app/shared/app-data/src/commonMain/kotlin/domain/media/fetch/MediaSourceManager.kt (revision c4a26dd127f645d798d8c6b0faff92a91c356ce5)
@@ -23,7 +23,6 @@
import kotlinx.coroutines.flow.shareIn
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.json.JsonElement
-import me.him188.ani.app.data.models.preference.ProxyAuthorization
import me.him188.ani.app.data.models.preference.ProxyConfig
import me.him188.ani.app.data.repository.media.MediaSourceInstanceRepository
import me.him188.ani.app.data.repository.media.MikanIndexCacheRepository
@@ -51,7 +50,6 @@
import me.him188.ani.datasources.mikan.MikanCNMediaSource
import me.him188.ani.datasources.mikan.MikanMediaSource
import me.him188.ani.utils.coroutines.onReplacement
-import me.him188.ani.utils.ktor.ClientProxyConfig
import me.him188.ani.utils.ktor.ScopedHttpClient
import me.him188.ani.utils.logging.error
import me.him188.ani.utils.logging.logger
@@ -333,10 +331,3 @@
private val logger = logger<MediaSourceManager>()
}
}
-
-fun ProxyConfig.toClientProxyConfig() = ClientProxyConfig(
- url = url,
- authorization = authorization?.toHeader(),
-)
-
-fun ProxyAuthorization.toHeader(): String = "Basic ${"$username:$password"}"
Index: app/shared/app-data/src/commonMain/kotlin/domain/settings/ProxyProvider.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/shared/app-data/src/commonMain/kotlin/domain/settings/ProxyProvider.kt b/app/shared/app-data/src/commonMain/kotlin/domain/settings/ProxyProvider.kt
--- a/app/shared/app-data/src/commonMain/kotlin/domain/settings/ProxyProvider.kt (revision 18f6bfb0139a118ae08a76292671c24959a57b2d)
+++ b/app/shared/app-data/src/commonMain/kotlin/domain/settings/ProxyProvider.kt (revision c4a26dd127f645d798d8c6b0faff92a91c356ce5)
@@ -28,7 +28,6 @@
import me.him188.ani.app.data.models.preference.ProxyConfig
import me.him188.ani.app.data.models.preference.ProxyMode
import me.him188.ani.app.data.repository.user.SettingsRepository
-import me.him188.ani.app.domain.media.fetch.toClientProxyConfig
import me.him188.ani.app.platform.SystemProxyDetector
import me.him188.ani.utils.ktor.setProxy
import me.him188.ani.utils.logging.info
复现步骤
No response
Ani 版本号
991f59d9086f17f5c756d8b772261de1d668571a
操作系统
No response
应用日志
图片上半部分是服务端日志。
2025-02-12 16:33:12,879 [ERROR] HttpClientProvider: GET https://api.bgm.tv/v0/users/-/collections/302189 : IO_EXCEPTION in 10.663200ms
2025-02-12 16:33:12,888 [WARN ] HttpClientProvider: GET https://s1.animeko.openani.org/v1/schedule/subjects?ids=302189 : CANCELLED in 34.094900ms
java.io.IOException: Failed to authenticate with proxy
at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt:42)
at io.ktor.client.engine.okhttp.OkHttpEngine.executeHttpRequest(OkHttpEngine.kt:103)
at io.ktor.client.engine.okhttp.OkHttpEngine.execute(OkHttpEngine.kt:70)
at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99)
at io.ktor.client.engine.HttpClientEngine$DefaultImpls.executeWithinCallContext(HttpClientEngine.kt:100)
at io.ktor.client.engine.HttpClientEngine$install$1.invokeSuspend(HttpClientEngine.kt:70)
at io.ktor.client.plugins.HttpSend$DefaultSender.execute(HttpSend.kt:138)
at me.him188.ani.app.domain.foundation.ServerListFeatureHandler$applyToClient$1.invokeSuspend(ScopedHttpClientFeature.kt:211)
at me.him188.ani.app.domain.foundation.UseBangumiTokenFeatureHandler$applyToClient$1.invokeSuspend(ScopedHttpClientFeature.kt:155)
at me.him188.ani.utils.ktor.DefaultClientKt$registerLogging$1.invokeSuspend(DefaultClient.kt:86)
at io.ktor.client.plugins.auth.Auth$Plugin$install$2.invokeSuspend(Auth.kt:67)
at io.ktor.client.plugins.HttpTimeout$Plugin$install$1.invokeSuspend(HttpTimeout.kt:174)
at io.ktor.client.plugins.HttpRequestRetry$intercept$1.invokeSuspend(HttpRequestRetry.kt:298)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invokeSuspend(HttpRedirect.kt:64)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invokeSuspend(HttpCallValidator.kt:151)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invokeSuspend(HttpSend.kt:104)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invokeSuspend(HttpCallValidator.kt:130)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invokeSuspend(HttpRequestLifecycle.kt:38)
at io.ktor.client.HttpClient.execute$ktor_client_core(HttpClient.kt:191)
at io.ktor.client.statement.HttpStatement.executeUnsafe(HttpStatement.kt:108)
at io.ktor.client.statement.HttpStatement.execute(HttpStatement.kt:47)
at me.him188.ani.datasources.bangumi.apis.DefaultApi.getUserCollection$suspendImpl(DefaultApi.kt:1369)
at me.him188.ani.app.data.network.RemoteBangumiSubjectService$subjectCollectionById$1$1.invokeSuspend(BangumiSubjectService.kt:424)
at me.him188.ani.utils.ktor.ApiInvokerKt$ApiInvoker$1.invoke(ApiInvoker.kt:25)
at me.him188.ani.app.data.network.RemoteBangumiSubjectService$subjectCollectionById$1.invokeSuspend(BangumiSubjectService.kt:424)
at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)
at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun$1.invokeSuspend(ChannelFlow.kt:56)
at kotlinx.coroutines.flow.FlowKt__ReduceKt.first(Reduce.kt:179)
at me.him188.ani.app.data.network.RemoteBangumiSubjectService.getSubjectCollection(BangumiSubjectService.kt:188)
at me.him188.ani.app.data.repository.subject.SubjectCollectionRepositoryImpl$subjectCollectionFlow$1$1$subjectCollectionDeferred$1.invokeSuspend(SubjectCollectionRepository.kt:226)
at me.him188.ani.app.data.repository.subject.SubjectCollectionRepositoryImpl$subjectCollectionFlow$1.invokeSuspend(SubjectCollectionRepository.kt:225)
at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1$2.emit(Transform.kt:50)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:33)
at kotlinx.coroutines.flow.internal.ChannelFlow$collect$2.invokeSuspend(ChannelFlow.kt:119)
at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2$1.invokeSuspend(Combine.kt:28)
at kotlinx.coroutines.flow.FlowKt__ShareKt$launchSharingDeferred$1.invokeSuspend(Share.kt:336)
at me.him188.ani.app.ui.subject.details.state.DefaultSubjectDetailsStateFactory$create$3.invokeSuspend(SubjectDetailsStateFactory.kt:192)
at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)
at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invokeSuspend(Merge.kt:23)
at me.him188.ani.app.ui.subject.details.state.SubjectDetailsStateLoader$load$1.invokeSuspend(SubjectDetailsStateLoader.kt:53)
Caused by: java.io.IOException: Failed to authenticate with proxy
at okhttp3.internal.connection.RealConnection.createTunnel(RealConnection.kt:476)
at okhttp3.internal.connection.RealConnection.connectTunnel(RealConnection.kt:262)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:201)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
看不出来什么,因为 Client 是之前创建好的
应该大部分代理都是无账号密码的 (clash 局域网)