This commit is contained in:
Horis
2025-04-21 22:37:51 +08:00
parent 1fabd3c4d8
commit 748ad34fe1
2 changed files with 52 additions and 5 deletions
@@ -2,6 +2,7 @@ package io.legado.app.help.http
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.http.SslError import android.net.http.SslError
import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.util.AndroidRuntimeException import android.util.AndroidRuntimeException
@@ -20,6 +21,9 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Runnable import kotlinx.coroutines.Runnable
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeout
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import org.apache.commons.text.StringEscapeUtils import org.apache.commons.text.StringEscapeUtils
import splitties.init.appCtx import splitties.init.appCtx
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -143,7 +147,20 @@ class BackstageWebView(
private inner class HtmlWebViewClient : WebViewClient() { 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) { override fun onPageFinished(view: WebView, url: String) {
setCookie(url) setCookie(url)
@@ -181,7 +198,7 @@ class BackstageWebView(
val content = StringEscapeUtils.unescapeJson(result) val content = StringEscapeUtils.unescapeJson(result)
.replace(quoteRegex, "") .replace(quoteRegex, "")
try { try {
val response = StrResponse(url, content) val response = buildStrResponse(content)
callback?.onResult(response) callback?.onResult(response)
} catch (e: Exception) { } catch (e: Exception) {
callback?.onError(e) callback?.onError(e)
@@ -201,6 +218,27 @@ class BackstageWebView(
retry++ retry++
mHandler.postDelayed(this@EvalJsRunnable, 1000) 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)
}
} }
} }
@@ -32,6 +32,8 @@ import kotlinx.coroutines.withTimeout
import org.apache.commons.text.StringEscapeUtils import org.apache.commons.text.StringEscapeUtils
import org.jsoup.nodes.Node import org.jsoup.nodes.Node
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import org.mozilla.javascript.Scriptable
import java.lang.ref.WeakReference
import java.net.URL import java.net.URL
import java.util.Locale import java.util.Locale
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -70,6 +72,7 @@ class AnalyzeRule(
private val stringRuleCache = hashMapOf<String, List<SourceRule>>() private val stringRuleCache = hashMapOf<String, List<SourceRule>>()
private val regexCache = hashMapOf<String, Regex?>() private val regexCache = hashMapOf<String, Regex?>()
private val scriptCache = hashMapOf<String, CompiledScript>() private val scriptCache = hashMapOf<String, CompiledScript>()
private var topScopeRef: WeakReference<Scriptable>? = null
private var coroutineContext: CoroutineContext = EmptyCoroutineContext private var coroutineContext: CoroutineContext = EmptyCoroutineContext
@@ -758,9 +761,15 @@ class AnalyzeRule(
bindings["nextChapterUrl"] = nextChapterUrl bindings["nextChapterUrl"] = nextChapterUrl
bindings["rssArticle"] = rssArticle bindings["rssArticle"] = rssArticle
} }
val scope = RhinoScriptEngine.getRuntimeScope(bindings) val topScope = source?.getShareScope(coroutineContext) ?: topScopeRef?.get()
source?.getShareScope(coroutineContext)?.let { val scope = if (topScope == null) {
scope.prototype = it RhinoScriptEngine.getRuntimeScope(bindings).apply {
topScopeRef = WeakReference(prototype)
}
} else {
bindings.apply {
prototype = topScope
}
} }
val script = compileScriptCache(jsStr) val script = compileScriptCache(jsStr)
return script.eval(scope, coroutineContext) return script.eval(scope, coroutineContext)