Aaron
Aaron

Reputation: 2755

Android Intercept a WebView request properly

My current code for intercepting a request in webview is

 @Override
public WebResourceResponse shouldInterceptRequest(WebView view,
    String url) {
    String ext = MimeTypeMap.getFileExtensionFromUrl(url);
    String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
    if (mime == null) {
        return super.shouldInterceptRequest(view, url);
    } else {
        HttpURLConnection conn = (HttpURLConnection) new URL(
                                                 url).openConnection();
        conn.setRequestProperty("User-Agent", userAgent);
        return new WebResourceResponse(mime, "UTF-8",
                                                 conn.getInputStream());
    }
}

I got this code from The best way to intercept a WebView request in Android.

However, whenever I try to perform authentication, let's say I am loading facebook in my webview.

mWebView.loadUrl("https://www.facebook.com/");

Nothing is happening, what I noticed is that, the request headers are incomplete and also the response. Also, there are no cookies in the Sources. (I saw this when I remotely debugged the webview through Chrome).

Please correct me if I'm wrong, but I think that the incomplete headers and missing cookies is what causing the login request to fail.

Is there a way where I can modify the request and set its headers? Also for the response, should I do it too? And finally, how will I be able to have the cookies.

Upvotes: 1

Views: 3638

Answers (1)

soey
soey

Reputation: 1158

This question hasn't been answered for 6 months, so I don't know whether you will still need this, but maybe someone else has a similar question.

request headers are incomplete

When using HttpURLConnection you will be responsible to set any request headers, you might need, but it is as simple as setting the User-Agent, which you already did: conn.setRequestHeader(header, value) or if you want to add and not overwrite a header value: conn.addRequestHeader(header, value)

Alternatively, you could use okhttp, a HTTP client, which should add default values for headers, that are commonly expected.

there are no cookies in the Sources

When intercepting the request, you will also be in charge for handling cookies. You could store the cookie manually, by parsing the headers from the response e.g.

    public WebResourceResponse shouldInterceptRequest(WebView view,
       String url) { 
       // do your stuff
       conn.connect(); // required to tell that the connection should be established
       String cookie = getCookieFromConnection(conn);
       // do more stuff and return WebResourceResponse
    }

    /**
     * iterates all headers, and finds "cookie" headers 
     * (there could be more than one)
     * @return cookie (concatenated value of all the found cookies)
     * or null if no cookie has been found
     */
    private String getCookieFromConnection(HttpURLConnection connection) {
       String cookie = "";
       Map<String, List<String>> header = connection.getHeaderFields();
       List<String> cookies = header.get(COOKIE_HEADER);
       if (cookies != null) {
           for (String c : cookies) {
               if (c != null) cookie += c + ";";
           }
       }
       if (cookie.isEmpty()) return null;
       return cookie;
}

or you could use a CookieManager, which would handle everything for you:

    cookieManager = new CookieManager();
    CookieHandler.setDefault(cookieManager); 
    cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

You could will also need to handle your cookies, when using okhttp, but again you could use the CookieManager as stated above. See this docu for more details, or this stackoverflow question.

Please correct me if I'm wrong, but I think that the incomplete headers and missing cookies is what causing the login request to fail.

There is another problem, when intercepting requests in a WebView: it somehow stops loading and evaluating javascript. I found this blog by Artem Zinnatullin online, who describes this behavior, and I experienced the same behavior.

If anyone would has a solution for this, I would be very happy.

Upvotes: 1

Related Questions