diff --git a/app/src/main/java/io/legado/app/help/http/BackstageWebView.kt b/app/src/main/java/io/legado/app/help/http/BackstageWebView.kt index 09b4c368b..e8176e713 100644 --- a/app/src/main/java/io/legado/app/help/http/BackstageWebView.kt +++ b/app/src/main/java/io/legado/app/help/http/BackstageWebView.kt @@ -2,6 +2,7 @@ package io.legado.app.help.http import android.annotation.SuppressLint import android.net.http.SslError +import android.os.Build import android.os.Handler import android.os.Looper import android.util.AndroidRuntimeException @@ -20,6 +21,9 @@ import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Runnable import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withTimeout +import okhttp3.Protocol +import okhttp3.Request +import okhttp3.Response import org.apache.commons.text.StringEscapeUtils import splitties.init.appCtx import java.lang.ref.WeakReference @@ -143,7 +147,20 @@ class BackstageWebView( private inner class HtmlWebViewClient : WebViewClient() { - var runnable: EvalJsRunnable? = null + private var runnable: EvalJsRunnable? = null + private var isRedirect = false + + override fun shouldOverrideUrlLoading( + view: WebView, + request: WebResourceRequest + ): Boolean { + isRedirect = isRedirect || if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + request.isRedirect + } else { + request.url.toString() != view.url + } + return super.shouldOverrideUrlLoading(view, request) + } override fun onPageFinished(view: WebView, url: String) { setCookie(url) @@ -181,7 +198,7 @@ class BackstageWebView( val content = StringEscapeUtils.unescapeJson(result) .replace(quoteRegex, "") try { - val response = StrResponse(url, content) + val response = buildStrResponse(content) callback?.onResult(response) } catch (e: Exception) { callback?.onError(e) @@ -201,6 +218,27 @@ class BackstageWebView( retry++ mHandler.postDelayed(this@EvalJsRunnable, 1000) } + + private fun buildStrResponse(content: String): StrResponse { + if (!isRedirect) { + return StrResponse(url, content) + } + val originUrl = this@BackstageWebView.url ?: url + val originResponse = Response.Builder() + .code(302) + .request(Request.Builder().url(originUrl).build()) + .protocol(Protocol.HTTP_1_1) + .message("Found") + .build() + val response = Response.Builder() + .code(200) + .request(Request.Builder().url(url).build()) + .protocol(Protocol.HTTP_1_1) + .message("OK") + .priorResponse(originResponse) + .build() + return StrResponse(response, content) + } } } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 3133393d5..e10da95f9 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -32,6 +32,8 @@ import kotlinx.coroutines.withTimeout import org.apache.commons.text.StringEscapeUtils import org.jsoup.nodes.Node import org.mozilla.javascript.NativeObject +import org.mozilla.javascript.Scriptable +import java.lang.ref.WeakReference import java.net.URL import java.util.Locale import java.util.regex.Pattern @@ -70,6 +72,7 @@ class AnalyzeRule( private val stringRuleCache = hashMapOf>() private val regexCache = hashMapOf() private val scriptCache = hashMapOf() + private var topScopeRef: WeakReference? = null private var coroutineContext: CoroutineContext = EmptyCoroutineContext @@ -758,9 +761,15 @@ class AnalyzeRule( bindings["nextChapterUrl"] = nextChapterUrl bindings["rssArticle"] = rssArticle } - val scope = RhinoScriptEngine.getRuntimeScope(bindings) - source?.getShareScope(coroutineContext)?.let { - scope.prototype = it + val topScope = source?.getShareScope(coroutineContext) ?: topScopeRef?.get() + val scope = if (topScope == null) { + RhinoScriptEngine.getRuntimeScope(bindings).apply { + topScopeRef = WeakReference(prototype) + } + } else { + bindings.apply { + prototype = topScope + } } val script = compileScriptCache(jsStr) return script.eval(scope, coroutineContext)