import android.content.Context import android.os.Handler import android.os.Looper import android.webkit.CookieManager import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response import okhttp3.ResponseBody import okhttp3.MediaType.Companion.toMediaTypeOrNull import java.io.IOException import java.util.concurrent.CountDownLatch interface AntiDDOSCookiesStorage { fun saveCookie(cookie: String) fun loadCookie(): String? } class AntiDdosInterceptor(private val context: Context, private val cookiesStorage: AntiDDOSCookiesStorage) : Interceptor { companion object { const val TARGET_STRING = "SomeLongString" } override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() var savedCookies = cookiesStorage.loadCookie() if (savedCookies == null) { val bodyFromWebView = loadPageWithWebView(originalRequest.url.toString()) savedCookies = cookiesStorage.loadCookie() if (bodyFromWebView != null && bodyFromWebView.contains(TARGET_STRING)) { return chain.proceed(originalRequest) .newBuilder() .body(ResponseBody.create("text/html".toMediaTypeOrNull(), bodyFromWebView)) .build() } } val requestWithCookies = originalRequest.newBuilder() .header("Cookie", savedCookies ?: "") .build() var response = chain.proceed(requestWithCookies) val responseBodyString = response.body?.string() ?: "" if (!responseBodyString.contains(TARGET_STRING)) { // If TARGET_STRING is not found, repeat the process response.close() val bodyFromWebView = loadPageWithWebView(originalRequest.url.toString()) savedCookies = cookiesStorage.loadCookie() val newRequestWithCookies = originalRequest.newBuilder() .header("Cookie", savedCookies ?: "") .build() response = chain.proceed(newRequestWithCookies) if (bodyFromWebView != null && bodyFromWebView.contains(TARGET_STRING)) { return response.newBuilder() .body(ResponseBody.create("text/html".toMediaTypeOrNull(), bodyFromWebView)) .build() } } return response.newBuilder() .body(ResponseBody.create("text/html".toMediaTypeOrNull(), responseBodyString)) .build() } private fun loadPageWithWebView(url: String): String? { val latch = CountDownLatch(1) val result = StringBuilder() Handler(Looper.getMainLooper()).post { val webView = WebView(context) val webSettings: WebSettings = webView.settings webSettings.javaScriptEnabled = true webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { view?.evaluateJavascript("(function() { return document.documentElement.outerHTML; })();") { html -> val cookieManager = CookieManager.getInstance() val cookies = cookieManager.getCookie(url) cookiesStorage.saveCookie(cookies) result.append(html) latch.countDown() } } } webView.loadUrl(url) } try { latch.await() } catch (e: InterruptedException) { e.printStackTrace() } return result.toString() } }