question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

bug: Android web view encapsulate 302 redirection response

See original GitHub issue

Bug 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:open
  • Created 3 years ago
  • Reactions:12
  • Comments:18

github_iconTop GitHub Comments

3reactions
sl45smscommented, Mar 6, 2021

@mrkelvinli, you are a lifesaver! Been really stuck on this for some days; your patch works fine. Hope soon to be merged.

2reactions
TimBroddincommented, Mar 30, 2021

Your patch made my day! Thanks a lot!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android WebView 302 Redirect - Honeycomb - Stack Overflow
I'm working on an Android application that uses a WebView and some 302 redirects to track link clicks. On Android 2.3.3, a 302...
Read more >
158771 - 302 redirect not working from js-embedded flash
The video src as specified in the page issues a 302 redirect to a video on a different server. DEMO: 1. Open Chrome's...
Read more >
How To Fix the HTTP 302 Error (5 Methods) - Kinsta
It's only an error if your website is responding with 302 codes that it shouldn't be issuing, or if it's causing a redirect...
Read more >
`<webview>` Tag | Electron
Use the webview tag to embed 'guest' content (such as web pages) in your Electron app. The guest content is contained within the...
Read more >
CSP: frame-ancestors - HTTP - MDN Web Docs - Mozilla
The HTTP Content-Security-Policy (CSP) frame-ancestors directive specifies valid parents that may embed a page using , , , , or .
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found