diff --git a/app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt index 2c7cc9f16..42bba8ade 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt @@ -55,7 +55,19 @@ class CloudflareInterceptor(private val context: Context) : Interceptor { val oldCookie = networkHelper.cookieManager.get(originalRequest.url) .firstOrNull { it.name == "cf_clearance" } resolveWithWebView(originalRequest, oldCookie) - return chain.proceed(originalRequest) + + // Avoid use empty User-Agent + return if (originalRequest.header("User-Agent").isNullOrEmpty()) { + val newRequest = originalRequest + .newBuilder() + .removeHeader("User-Agent") + .addHeader("User-Agent", + DEFAULT_USERAGENT) + .build() + chain.proceed(newRequest) + } else { + chain.proceed(originalRequest) + } } catch (e: Exception) { // Because OkHttp's enqueue only handles IOExceptions, wrap the exception so that // we don't crash the entire app @@ -77,20 +89,23 @@ class CloudflareInterceptor(private val context: Context) : Interceptor { val origRequestUrl = request.url.toString() val headers = request.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" } + val withUserAgent = request.header("User-Agent").isNullOrEmpty() handler.post { val webview = WebView(context) webView = webview - webview.settings.javaScriptEnabled = true + + // Avoid set empty User-Agent, Chromium WebView will reset to default if empty webview.settings.userAgentString = request.header("User-Agent") + ?: DEFAULT_USERAGENT webview.webViewClient = object : WebViewClientCompat() { override fun onPageFinished(view: WebView, url: String) { fun isCloudFlareBypassed(): Boolean { return networkHelper.cookieManager.get(origRequestUrl.toHttpUrl()) .firstOrNull { it.name == "cf_clearance" } - .let { it != null && it != oldCookie } + .let { it != null && (it != oldCookie || withUserAgent) } } if (isCloudFlareBypassed()) { @@ -156,5 +171,6 @@ class CloudflareInterceptor(private val context: Context) : Interceptor { companion object { private val SERVER_CHECK = arrayOf("cloudflare-nginx", "cloudflare") private val COOKIE_NAMES = listOf("__cfduid", "cf_clearance") + private const val DEFAULT_USERAGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64)" } }