From a24c9e4f8c48063d50de5166adb2a261aa039b02 Mon Sep 17 00:00:00 2001 From: ag2s20150909 Date: Sat, 7 May 2022 14:54:06 +0800 Subject: [PATCH] Cronet support cookieJar --- .../io/legado/app/help/http/HttpHelper.kt | 37 ++++++++-------- .../app/help/http/cronet/CronetInterceptor.kt | 42 +++++++++---------- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index a19e2b03c..c5cb6ea79 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -4,13 +4,7 @@ import io.legado.app.constant.AppConst import io.legado.app.help.config.AppConfig import io.legado.app.help.http.cronet.CronetInterceptor import io.legado.app.help.http.cronet.CronetLoader -import okhttp3.ConnectionSpec -import okhttp3.Credentials -import okhttp3.CookieJar -import okhttp3.Cookie -import okhttp3.HttpUrl -import okhttp3.Interceptor -import okhttp3.OkHttpClient +import okhttp3.* import java.net.InetSocketAddress import java.net.Proxy import java.util.concurrent.ConcurrentHashMap @@ -20,6 +14,22 @@ private val proxyClientCache: ConcurrentHashMap by lazy { ConcurrentHashMap() } +val cookieJar by lazy { + object : CookieJar { + + override fun loadForRequest(url: HttpUrl): List { + return emptyList() + } + + override fun saveFromResponse(url: HttpUrl, cookies: List) { + cookies.forEach { + CookieStore.replaceCookie(url.toString(), "${it.name}=${it.value}") + } + } + + } +} + val okHttpClient: OkHttpClient by lazy { val specs = arrayListOf( ConnectionSpec.MODERN_TLS, @@ -32,16 +42,7 @@ val okHttpClient: OkHttpClient by lazy { .writeTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .callTimeout(60, TimeUnit.SECONDS) - .cookieJar(object : CookieJar { - override fun saveFromResponse(url: HttpUrl, cookies: List) { - cookies.forEach { - CookieStore.replaceCookie(url.toString(), "${it.name}=${it.value}") - } - } - override fun loadForRequest(url: HttpUrl): List { - return ArrayList() - } - }) + .cookieJar(cookieJar = cookieJar) .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager) .retryOnConnectionFailure(true) .hostnameVerifier(SSLHelper.unsafeHostnameVerifier) @@ -60,7 +61,7 @@ val okHttpClient: OkHttpClient by lazy { chain.proceed(builder.build()) }) if (!AppConfig.isGooglePlay && AppConfig.isCronet && CronetLoader.install()) { - builder.addInterceptor(CronetInterceptor(null)) + builder.addInterceptor(CronetInterceptor(cookieJar = cookieJar)) } builder.build() } diff --git a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt index 30176c3cd..ffd701268 100644 --- a/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt +++ b/app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt @@ -1,12 +1,12 @@ package io.legado.app.help.http.cronet import android.os.Build -import io.legado.app.help.http.CookieStore import io.legado.app.utils.printOnDebug import okhttp3.* +import okhttp3.internal.http.receiveHeaders -class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { +class CronetInterceptor(private val cookieJar: CookieJar = CookieJar.NO_COOKIES) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val original: Request = chain.request() @@ -18,15 +18,18 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { //移除Keep-Alive,手动设置会导致400 BadRequest builder.removeHeader("Keep-Alive") builder.removeHeader("Accept-Encoding") - val cookieStr = getCookie(original.url) - //设置Cookie - if (cookieStr.length > 3) { - builder.header("Cookie", cookieStr) + if (cookieJar != CookieJar.NO_COOKIES) { + val cookieStr = getCookie(original.url) + //设置Cookie + if (cookieStr.length > 3) { + builder.addHeader("Cookie", cookieStr) + } } - val new = builder.build() - proceedWithCronet(new, chain.call())?.let { response -> + + val newReq = builder.build() + proceedWithCronet(newReq, chain.call())?.let { response -> //从Response 中保存Cookie到CookieJar - cookieJar?.saveFromResponse(new.url, Cookie.parseAll(new.url, response.headers)) + cookieJar.receiveHeaders(newReq.url, response.headers) response } ?: chain.proceed(original) } catch (e: Exception) { @@ -54,21 +57,14 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { return null } - private fun getCookie(url: HttpUrl): String { - val sb = StringBuilder() - //处理从 Cookiejar 获取到的Cookies - if (cookieJar != null) { - val cookies = cookieJar.loadForRequest(url) - for (cookie in cookies) { - sb.append(cookie.name).append("=").append(cookie.value).append("; ") - } - } - //处理自定义的Cookie - val cookie = CookieStore.getCookie(url.toString()) - if (cookie.length > 3) { - sb.append(cookie) + + /** Returns a 'Cookie' HTTP request header with all cookies, like `a=b; c=d`. */ + private fun getCookie(url: HttpUrl): String = buildString { + val cookies = cookieJar.loadForRequest(url) + cookies.forEachIndexed { index, cookie -> + if (index > 0) append("; ") + append(cookie.name).append('=').append(cookie.value) } - return sb.toString() } }