From 38abcb95090a3917ad5092f4933acb95c721f893 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Thu, 15 Aug 2024 22:07:26 -0300 Subject: [PATCH] fix(android): custom protocol not triggered on redirect (#1340) The shouldInterceptRequest function is not called on redirects, which means any redirect to a custom protocol URL will fail to load, so we must apply a small check in the onReceivedError function. This changes the Android implementation to handle URL load errors to retry loading the URL to give a chance of the custom protocol function to handle the request. --- .../fix-android-custom-protocol-redirect.md | 5 +++++ src/android/kotlin/RustWebViewClient.kt | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 .changes/fix-android-custom-protocol-redirect.md diff --git a/.changes/fix-android-custom-protocol-redirect.md b/.changes/fix-android-custom-protocol-redirect.md new file mode 100644 index 000000000..f59034ffb --- /dev/null +++ b/.changes/fix-android-custom-protocol-redirect.md @@ -0,0 +1,5 @@ +--- +"wry": patch +--- + +Fixes custom protocols not triggered on Android on external redirects. diff --git a/src/android/kotlin/RustWebViewClient.kt b/src/android/kotlin/RustWebViewClient.kt index 3b69dcab7..843451c39 100644 --- a/src/android/kotlin/RustWebViewClient.kt +++ b/src/android/kotlin/RustWebViewClient.kt @@ -4,6 +4,7 @@ package {{package}} +import android.net.Uri import android.webkit.* import android.content.Context import android.graphics.Bitmap @@ -12,6 +13,7 @@ import androidx.webkit.WebViewAssetLoader class RustWebViewClient(context: Context): WebViewClient() { private val interceptedState = mutableMapOf() var currentUrl: String = "about:blank" + var lastInterceptedUrl: Uri? = null private val assetLoader = WebViewAssetLoader.Builder() .setDomain(assetLoaderDomain()) @@ -22,6 +24,7 @@ class RustWebViewClient(context: Context): WebViewClient() { view: WebView, request: WebResourceRequest ): WebResourceResponse? { + lastInterceptedUrl = request.url return if (withAssetLoader()) { assetLoader.shouldInterceptRequest(request.url) } else { @@ -53,6 +56,20 @@ class RustWebViewClient(context: Context): WebViewClient() { return onPageLoaded(url) } + override fun onReceivedError( + view: WebView, + request: WebResourceRequest, + error: WebResourceError + ) { + // we get a net::ERR_CONNECTION_REFUSED when an external URL redirects to a custom protocol + // e.g. oauth flow, because shouldInterceptRequest is not called on redirects + // so we must force retry here with loadUrl() to get a chance of the custom protocol to kick in + if (error.errorCode == ERROR_CONNECT && request.url != lastInterceptedUrl) { + view.loadUrl(request.url.toString()) + } else { + super.onReceivedError(view, request, error) + } + } companion object { init {