Merge pull request #121 from Blatzar/master

Added WebViewResolver.kt to bypass captcha and such evils
This commit is contained in:
Osten 2021-10-04 20:08:23 +02:00 committed by GitHub
commit d86a80ae14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 6 deletions

View file

@ -14,6 +14,7 @@ import org.acra.data.StringFormat
import org.acra.ktx.initAcra import org.acra.ktx.initAcra
import org.acra.sender.ReportSender import org.acra.sender.ReportSender
import org.acra.sender.ReportSenderFactory import org.acra.sender.ReportSenderFactory
import java.lang.ref.WeakReference
import kotlin.concurrent.thread import kotlin.concurrent.thread
class CustomReportSender : ReportSender { class CustomReportSender : ReportSender {
@ -55,6 +56,7 @@ class CustomSenderFactory : ReportSenderFactory {
class AcraApplication : Application() { class AcraApplication : Application() {
override fun attachBaseContext(base: Context?) { override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base) super.attachBaseContext(base)
context = base
initAcra { initAcra {
//core configuration: //core configuration:
@ -75,4 +77,14 @@ class AcraApplication : Application() {
}*/ }*/
} }
} }
companion object {
private var _context: WeakReference<Context>? = null
var context
get() = _context?.get()
private set(value) {
_context = WeakReference(value)
}
}
} }

View file

@ -73,9 +73,10 @@ fun getCache(cacheTime: Int, cacheUnit: TimeUnit): CacheControl {
fun getHeaders(headers: Map<String, String>, referer: String?, cookie: Map<String, String>): Headers { fun getHeaders(headers: Map<String, String>, referer: String?, cookie: Map<String, String>): Headers {
val refererMap = (referer ?: DEFAULT_REFERER)?.let { mapOf("referer" to it) } ?: mapOf() val refererMap = (referer ?: DEFAULT_REFERER)?.let { mapOf("referer" to it) } ?: mapOf()
val cookieHeaders = (DEFAULT_COOKIES + cookie) val cookieHeaders = (DEFAULT_COOKIES + cookie)
val cookieMap = if(cookieHeaders.isNotEmpty()) mapOf("Cookie" to cookieHeaders.entries.joinToString(separator = "; ") { val cookieMap =
"${it.key}=${it.value};" if (cookieHeaders.isNotEmpty()) mapOf("Cookie" to cookieHeaders.entries.joinToString(separator = "; ") {
}) else mapOf() "${it.key}=${it.value};"
}) else mapOf()
val tempHeaders = (DEFAULT_HEADERS + cookieMap + headers + refererMap) val tempHeaders = (DEFAULT_HEADERS + cookieMap + headers + refererMap)
return tempHeaders.toHeaders() return tempHeaders.toHeaders()
} }
@ -89,16 +90,19 @@ fun get(
allowRedirects: Boolean = true, allowRedirects: Boolean = true,
cacheTime: Int = DEFAULT_TIME, cacheTime: Int = DEFAULT_TIME,
cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, cacheUnit: TimeUnit = DEFAULT_TIME_UNIT,
timeout: Long = 0L timeout: Long = 0L,
interceptor: Interceptor? = null
): Response { ): Response {
val client = OkHttpClient().newBuilder() val client = OkHttpClient().newBuilder()
.followRedirects(allowRedirects) .followRedirects(allowRedirects)
.followSslRedirects(allowRedirects) .followSslRedirects(allowRedirects)
.callTimeout(timeout, TimeUnit.SECONDS) .callTimeout(timeout, TimeUnit.SECONDS)
.build()
if (interceptor != null) client.addInterceptor(interceptor)
val request = getRequestCreator(url, headers, referer, params, cookies, cacheTime, cacheUnit) val request = getRequestCreator(url, headers, referer, params, cookies, cacheTime, cacheUnit)
return client.newCall(request).execute() return client.build().newCall(request).execute()
} }

View file

@ -0,0 +1,90 @@
package com.lagradost.cloudstream3.network
import android.annotation.SuppressLint
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import com.lagradost.cloudstream3.AcraApplication
import com.lagradost.cloudstream3.utils.Coroutines.main
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import java.util.concurrent.TimeUnit
class WebViewResolver(val interceptUrl: Regex) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
return runBlocking {
val fixedRequest = resolveUsingWebView(request)
return@runBlocking chain.proceed(fixedRequest ?: request)
}
}
@SuppressLint("SetJavaScriptEnabled")
suspend fun resolveUsingWebView(request: Request): Request? {
val url = request.url.toString()
var webView: WebView? = null
fun destroyWebView() {
main {
webView?.stopLoading()
webView?.destroy()
webView = null
println("Destroyed webview")
}
}
var fixedRequest: Request? = null
main {
webView = WebView(
AcraApplication.context ?: throw RuntimeException("No base context in WebViewResolver")
).apply {
settings.javaScriptEnabled = true
}
webView?.webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
val webViewUrl = request.url.toString()
if (interceptUrl.containsMatchIn(webViewUrl)) {
fixedRequest = getRequestCreator(
webViewUrl,
request.requestHeaders,
null,
mapOf(),
mapOf(),
10,
TimeUnit.MINUTES
)
destroyWebView()
}
return super.shouldInterceptRequest(view, request)
}
}
webView?.loadUrl(url)
}
var loop = 0
// Timeouts after this amount, 20s
val totalTime = 20000L
val delayTime = 100L
// A bit sloppy, but couldn't find a better way
while (loop < totalTime / delayTime) {
if (fixedRequest != null) return fixedRequest
delay(delayTime)
loop += 1
}
destroyWebView()
return null
}
}