From e4719dca85874de9e043cc5d30c803ed040d4602 Mon Sep 17 00:00:00 2001 From: Nazar78 Date: Wed, 8 Sep 2021 07:45:24 +0800 Subject: [PATCH] Workaround for serviceWorker cache prevent injections (#526) * Workaround for serviceWorker cache prevent injections * Use compat APIs, return 404 instead of comment Co-authored-by: Maxr1998 --- .../mobile/fragment/WebViewFragment.kt | 23 ++++++++++++++++++- .../org/jellyfin/mobile/utils/Constants.kt | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt b/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt index d911c3b2..78d22560 100644 --- a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt +++ b/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt @@ -27,11 +27,14 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.add import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.webkit.ServiceWorkerClientCompat +import androidx.webkit.ServiceWorkerControllerCompat import androidx.webkit.WebResourceErrorCompat import androidx.webkit.WebViewAssetLoader.AssetsPathHandler import androidx.webkit.WebViewClientCompat import androidx.webkit.WebViewCompat import androidx.webkit.WebViewFeature +import io.ktor.http.HttpStatusCode import kotlinx.coroutines.launch import org.jellyfin.mobile.AppPreferences import org.jellyfin.mobile.R @@ -162,7 +165,6 @@ class WebViewFragment : Fragment(), NativePlayerHost { showOutdatedWebViewDialog(this) return } - webViewClient = object : WebViewClientCompat() { override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? { val url = request.url @@ -231,6 +233,25 @@ class WebViewFragment : Fragment(), NativePlayerHost { onErrorReceived() } } + // Workaround for service worker breaking script injections + if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) { + val swController = ServiceWorkerControllerCompat.getInstance() + swController.setServiceWorkerClient(object : ServiceWorkerClientCompat() { + override fun shouldInterceptRequest(request: WebResourceRequest): WebResourceResponse? { + val path = request.url.path?.lowercase(Locale.ROOT) ?: return null + return when { + path.endsWith(Constants.SERVICE_WORKER_PATH) -> { + WebResourceResponse("application/javascript", "utf-8", null).apply { + with(HttpStatusCode.NotFound) { + setStatusCodeAndReasonPhrase(value, description) + } + } + } + else -> null + } + } + }) + } webChromeClient = object : WebChromeClient() { override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean { val logLevel = when (consoleMessage.messageLevel()) { diff --git a/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt b/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt index 2db014d7..cd5fe970 100644 --- a/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt +++ b/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt @@ -17,6 +17,7 @@ object Constants { val MAIN_BUNDLE_PATH_REGEX = Regex(""".*/main\.[^/\s]+\.bundle\.js""") const val CAST_SDK_PATH = "cast_sender.js" const val SESSION_CAPABILITIES_PATH = "sessions/capabilities/full" + const val SERVICE_WORKER_PATH = "serviceworker.js" const val FRAGMENT_CONNECT_EXTRA_ERROR = "org.jellyfin.mobile.intent.extra.ERROR" const val FRAGMENT_WEB_VIEW_EXTRA_SERVER = "org.jellyfin.mobile.intent.extra.SERVER"