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 <max.rumpf1998@gmail.com>
This commit is contained in:
Nazar78
2021-09-07 23:45:24 +00:00
committed by GitHub
co-authored by Maxr1998
parent 8376f4df87
commit e4719dca85
2 changed files with 23 additions and 1 deletions
@@ -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()) {
@@ -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"