Преглед изворни кода

Merge pull request #1854 from ag2s20150909/master

Cronet support cookieJar
kunfei пре 4 година
родитељ
комит
c1ff40e5d2

+ 19 - 18
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<String, OkHttpClient> by lazy {
     ConcurrentHashMap()
 }
 
+val cookieJar by lazy {
+    object : CookieJar {
+
+        override fun loadForRequest(url: HttpUrl): List<Cookie> {
+            return emptyList()
+        }
+
+        override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
+            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<Cookie>) {
-                 cookies.forEach {
-                     CookieStore.replaceCookie(url.toString(), "${it.name}=${it.value}")
-                 }
-            }
-            override fun loadForRequest(url: HttpUrl): List<Cookie> {
-                return ArrayList<Cookie>()
-            }
-        })
+        .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()
 }

+ 19 - 23
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()
     }
 
 }