Просмотр исходного кода

Merge pull request #1852 from Xwite/master

fix:验证码不缓存
kunfei 4 лет назад
Родитель
Сommit
a201f87efc

+ 6 - 0
app/src/main/java/io/legado/app/data/entities/BaseSource.kt

@@ -95,11 +95,17 @@ interface BaseSource : JsExtensions {
      * 保存登录头部信息,map格式,访问时自动添加
      */
     fun putLoginHeader(header: String) {
+        val headerMap = GSON.fromJsonObject<Map<String, String>>(header).getOrNull()
+        val cookie = headerMap?.get("Cookie") ?: headerMap?.get("cookie")
+        cookie?.let {
+            CookieStore.replaceCookie(getKey(), it)
+        }
         CacheManager.put("loginHeader_${getKey()}", header)
     }
 
     fun removeLoginHeader() {
         CacheManager.delete("loginHeader_${getKey()}")
+        CookieStore.removeCookie(getKey())
     }
 
     /**

+ 15 - 19
app/src/main/java/io/legado/app/help/CacheManager.kt

@@ -11,7 +11,7 @@ import splitties.init.appCtx
 object CacheManager {
 
     private val queryTTFMap = hashMapOf<String, Pair<Long, QueryTTF>>()
-    private val memoryLruCache = object : LruCache<String, Cache>(100) {}
+    private val memoryLruCache = object : LruCache<String, String>(100) {}
 
     /**
      * saveTime 单位为秒
@@ -25,15 +25,23 @@ object CacheManager {
             is ByteArray -> ACache.get(appCtx).put(key, value, saveTime)
             else -> {
                 val cache = Cache(key, value.toString(), deadline)
-                memoryLruCache.put(key, cache)
+                putMemory(key, value.toString())
                 appDb.cacheDao.insert(cache)
             }
         }
     }
 
-    fun putMemory(key: String, value: Any) {
-        val cache = Cache(key, value.toString(), 0)
-        memoryLruCache.put(key, cache)
+    fun putMemory(key: String, value: String) {
+        memoryLruCache.put(key, value)
+    }
+
+    //从内存中获取数据 使用lruCache
+    fun getFromMemory(key: String): String? {
+        return memoryLruCache.get(key)
+    }
+
+    fun deleteMemory(key: String) {
+        memoryLruCache.remove(key)
     }
 
     fun get(key: String): String? {
@@ -42,24 +50,12 @@ object CacheManager {
         }
         val cache = appDb.cacheDao.get(key)
         if (cache != null && (cache.deadline == 0L || cache.deadline > System.currentTimeMillis())) {
-            memoryLruCache.put(key, cache)
+            putMemory(key, cache.value ?: "")
             return cache.value
         }
         return null
     }
 
-    //从内存中获取数据 使用lruCache 支持过期功能
-    private fun getFromMemory(key: String): String? {
-        val cache = memoryLruCache.get(key) ?: return null
-        val deadline = cache.deadline
-        return if (deadline == 0L || deadline > System.currentTimeMillis()) {
-            cache.value
-        } else {
-            memoryLruCache.remove(key)
-            null
-        }
-    }
-
     fun getInt(key: String): Int? {
         return get(key)?.toIntOrNull()
     }
@@ -100,7 +96,7 @@ object CacheManager {
 
     fun delete(key: String) {
         appDb.cacheDao.delete(key)
-        memoryLruCache.remove(key)
+        deleteMemory(key)
         ACache.get(appCtx).remove(key)
     }
 }

+ 8 - 3
app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt

@@ -8,9 +8,11 @@ import com.bumptech.glide.load.data.DataFetcher
 import com.bumptech.glide.load.model.GlideUrl
 import com.bumptech.glide.util.ContentLengthInputStream
 import com.bumptech.glide.util.Preconditions
+import io.legado.app.constant.AppConst
 import io.legado.app.data.appDb
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.http.okHttpClient
+import io.legado.app.help.http.addHeaders
 import io.legado.app.utils.isWifiConnect
 import okhttp3.Call
 import okhttp3.Request
@@ -37,16 +39,19 @@ class OkHttpStreamFetcher(private val url: GlideUrl, private val options: Option
             return
         }
         val requestBuilder: Request.Builder = Request.Builder().url(url.toStringUrl())
+        val headerMap = HashMap<String, String>()
+        
         options.get(OkHttpModelLoader.sourceOriginOption)?.let { sourceUrl ->
             val source = appDb.bookSourceDao.getBookSource(sourceUrl)
                 ?: appDb.rssSourceDao.getByKey(sourceUrl)
-            source?.getHeaderMap(true)?.forEach {
-                requestBuilder.addHeader(it.key, it.value)
+            source?.getHeaderMap(true)?.let {
+                headerMap.putAll(it)
             }
         }
         for ((key, value) in url.headers.entries) {
-            requestBuilder.addHeader(key, value)
+            headerMap.put(key, value)
         }
+        requestBuilder.addHeaders(headerMap)
         val request: Request = requestBuilder.build()
         this.callback = callback
         call = okHttpClient.newCall(request)

+ 13 - 4
app/src/main/java/io/legado/app/help/http/CookieStore.kt

@@ -6,6 +6,7 @@ import android.text.TextUtils
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.Cookie
 import io.legado.app.help.http.api.CookieManager
+import io.legado.app.help.CacheManager
 import io.legado.app.utils.NetworkUtils
 
 object CookieStore : CookieManager {
@@ -14,7 +15,9 @@ object CookieStore : CookieManager {
      *保存cookie到数据库,会自动识别url的二级域名
      */
     override fun setCookie(url: String, cookie: String?) {
-        val cookieBean = Cookie(NetworkUtils.getSubDomain(url), cookie ?: "")
+        val domain = NetworkUtils.getSubDomain(url)
+        CacheManager.putMemory("${domain}_cookie", cookie ?: "")
+        val cookieBean = Cookie(domain, cookie ?: "")
         appDb.cookieDao.insert(cookieBean)
     }
 
@@ -37,8 +40,12 @@ object CookieStore : CookieManager {
      *获取url所属的二级域名的cookie
      */
     override fun getCookie(url: String): String {
-        val cookieBean = appDb.cookieDao.get(NetworkUtils.getSubDomain(url))
-        return cookieBean?.cookie ?: ""
+        val domain = NetworkUtils.getSubDomain(url)
+        CacheManager.getFromMemory("${domain}_cookie")?.let { return it }
+        val cookieBean = appDb.cookieDao.get(domain)
+        val cookie = cookieBean?.cookie ?: ""
+        CacheManager.putMemory(url, cookie ?: "")
+        return cookie
     }
 
     fun getKey(url: String, key: String): String {
@@ -48,7 +55,9 @@ object CookieStore : CookieManager {
     }
 
     override fun removeCookie(url: String) {
-        appDb.cookieDao.delete(NetworkUtils.getSubDomain(url))
+        val domain = NetworkUtils.getSubDomain(url)
+        CacheManager.deleteMemory("${domain}_cookie")
+        appDb.cookieDao.delete(domain)
     }
 
     override fun cookieToMap(cookie: String): MutableMap<String, String> {

+ 13 - 0
app/src/main/java/io/legado/app/help/http/HttpHelper.kt

@@ -6,6 +6,9 @@ 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 java.net.InetSocketAddress
@@ -29,6 +32,16 @@ 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>()
+            }
+        })
         .sslSocketFactory(SSLHelper.unsafeSSLSocketFactory, SSLHelper.unsafeTrustManager)
         .retryOnConnectionFailure(true)
         .hostnameVerifier(SSLHelper.unsafeHostnameVerifier)

+ 0 - 3
app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt

@@ -192,9 +192,6 @@ class AnalyzeUrl(
                     }
                 }
         }
-        headerMap[UA_NAME] ?: let {
-            headerMap[UA_NAME] = AppConfig.userAgent
-        }
         urlNoQuery = url
         when (method) {
             RequestMethod.GET -> {

+ 5 - 3
app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt

@@ -7,6 +7,7 @@ import android.view.ViewGroup
 import android.view.MenuItem
 import androidx.appcompat.widget.Toolbar
 import com.bumptech.glide.request.RequestOptions
+import com.bumptech.glide.load.engine.DiskCacheStrategy
 import io.legado.app.R
 import io.legado.app.base.BaseDialogFragment
 import io.legado.app.databinding.DialogVerificationCodeViewBinding
@@ -46,7 +47,6 @@ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification
         binding.run {
             toolBar.setBackgroundColor(primaryColor)
             val sourceOrigin = arguments?.getString("sourceOrigin")
-            val key = "${sourceOrigin}_verificationResult"
             arguments?.getString("imageUrl")?.let { imageUrl ->
                 ImageLoader.load(requireContext(), imageUrl).apply {
                     sourceOrigin?.let {
@@ -58,8 +58,10 @@ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification
                         )
                     }
                 }.error(R.drawable.image_loading_error)
-                    .into(ivImage)
-                ivImage.setOnClickListener {
+                    .diskCacheStrategy(DiskCacheStrategy.NONE)
+                    .skipMemoryCache(true)
+                    .into(verificationCodeImageView)
+                verificationCodeImageView.setOnClickListener {
                     showDialogFragment(PhotoDialog(imageUrl, sourceOrigin))
                 }
             }

+ 3 - 4
app/src/main/res/layout/dialog_verification_code_view.xml

@@ -18,11 +18,10 @@
         app:titleTextAppearance="@style/ToolbarTitle" />
 
     <androidx.appcompat.widget.AppCompatImageView
-        android:id="@+id/iv_image"
-        android:scaleType="fitXY"
+        android:id="@+id/verification_code_image_view"
         android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:padding="3dp"
+        android:layout_height="100dp"
+        android:scaleType="centerCrop"
         android:background="?android:attr/selectableItemBackgroundBorderless"
         tools:ignore="UnusedAttribute" />