bug: Android web view encapsulate 302 redirection response
See original GitHub issueBug Report
Capacitor Version
💊 Capacitor Doctor 💊
Latest Dependencies:
@capacitor/cli: 2.4.6
@capacitor/core: 2.4.6
@capacitor/android: 2.4.6
@capacitor/electron: 2.4.6
@capacitor/ios: 2.4.6
Installed Dependencies:
@capacitor/cli 2.4.2
@capacitor/android 2.4.2
@capacitor/core 2.4.2
@capacitor/ios 2.4.2
@capacitor/electron not installed
Platform(s)
Only on android
Current Behavior
When the android web view navigates to a URL that supposed to returns a 302 redirection response to a different domain, a 200 response was received with the HTML content. So that the web view does not perform any URL redirection. Instead the window URL remain unchanged. Assets (eg. images, CSS, static JS files) with relative URLs in the HTML reference the original window URL rather than the redirected URL. A broken HTML page is shown as a result of missing assets required by the HTML.
Expected Behavior
When navigating to URL which returns a 302 response, the web view should perform the redirection instead of it being resolved by Capacitor. The web view window location should be updated to the redirected location and the assets with relative URL in the HTML should be resolved with the correct URL path
Code Reproduction
Navigating to any URL which returns a 302 redirection response to a different domain produce this issue.
I made a repo to reproduce the issue here: https://github.com/mrkelvinli/capacitor-android-issue-4240-reproduction
Other Technical Details
npm --version
output: 6.14.10
node --version
output: v14.15.4
pod --version
output (iOS issues only):
Additional Context
I did some investigation on this in @capacitor/android
When the web view made a request to the serverUrl domain, Capacitor will proxy the network request from the web view into WebViewLocalServer. If the request in shouldInterceptRequest
is pass into handleProxyRequest()
, that means it has a PathHandler associated to the hostname of the request. If the request also has text/html
in the HTTP accept header, then the HttpURLConnection
object which performs the network request will follow redirects by default (as HttpURLConnection::setFollowRedirects()
is true by default). Thus, all successfully request will result in a 200 (status code is from the PathHandler associated to the request hostname) response and redirection will be resolved within HttpURLConnection
instead of the web view.
Solution I propose
diff --git a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java
index d632065..bc10831 100755
--- a/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java
+++ b/node_modules/@capacitor/android/capacitor/src/main/java/com/getcapacitor/WebViewLocalServer.java
@@ -311,6 +311,28 @@ public class WebViewLocalServer {
conn.setRequestMethod(method);
conn.setReadTimeout(30 * 1000);
conn.setConnectTimeout(30 * 1000);
+
+ /**
+ * This should be the final step in the setup process of the HttpURLConnection object.
+ *
+ * Initiate the connection with follow redirects disable. It allows us
+ * identifying any redirection response and avoid intercepting such request.
+ * This is because returning a 200 response when a redirection response (ie. 301 or 302)
+ * is expected could result in issues with resolving relative URLs for static assets
+ * in the HTML.
+ */
+ conn.setInstanceFollowRedirects(false);
+ conn.connect();
+ int status = conn.getResponseCode();
+ if (
+ status == HttpURLConnection.HTTP_MOVED_TEMP ||
+ status == HttpURLConnection.HTTP_MOVED_PERM ||
+ status == HttpURLConnection.HTTP_SEE_OTHER
+ ) {
+ // Return null so that this request will not be intercepted.
+ return null;
+ }
+
String cookie = conn.getHeaderField("Set-Cookie");
if (cookie != null) {
CookieManager.getInstance().setCookie(url, cookie);
Issue Analytics
- State:
- Created 3 years ago
- Reactions:12
- Comments:18
Top GitHub Comments
@mrkelvinli, you are a lifesaver! Been really stuck on this for some days; your patch works fine. Hope soon to be merged.
Your patch made my day! Thanks a lot!