1

I'm trying to intercept every request sent by a WebView and modify the headers before executing the request. There are a bunch of examples of how to do this (like this one), but I can't quite get it to work. Pages are able to load fine, but all of the requests look something like this in the Chrome debugger; they warn that "Provisional headers are shown" and none of my headers are present.

Here is the relevant section of my code:

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
        setWebViewClient(new MyWebViewClient());
    }

    private class MyWebViewClient extends WebViewClient {

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            WebResourceResponse response = null;
            try {
                URL url = new URL(request.getUrl().toString());
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod(request.getMethod());
                conn.setRequestProperty("test-header", "test-value");

                InputStream data;
                if (conn.getResponseCode() / 100 == 2) {
                    data = conn.getInputStream();
                }
                else {
                    data = conn.getErrorStream();
                }

                response = new WebResourceResponse("text/html", "UTF-8", data);
            }
            catch (IOException e) {

            }

            return response;
        }
    }
}

I also tried using OkHttp instead, but got the same results. Anyone able to get this working?

Connor V
  • 11
  • 4

2 Answers2

0

Try this instead, over shouldOverrideUrlLoading instead of shouldInterceptRequest

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
        setWebViewClient(new MyWebViewClient());
    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
        {
            final String url = request.getUrl().toString();
            return getNewResponse(url);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            return getNewResponse(url);
        }

        private WebResourceResponse getNewResponse(String url) {
            final OkHttpClient httpClient = new OkHttpClient();
            Response response = null;
            try {
                final Request request = new Request.Builder()
                        .url(url.trim())
                        .addHeader("test-header", "test-value")
                        .build();
                response = httpClient.newCall(request).execute();
            }
            catch (Exception e) {
            }
            if (response == null) {
                return null;
            }
            return new WebResourceResponse(
                    getMimeType(url),
                    response.header("content-encoding", "utf-8"),
                    response.body().byteStream()
            );
        }

        private String getMimeType(String url) {
            final String extension = MimeTypeMap.getFileExtensionFromUrl(url);

            if (extension == null) {
                return null;
            }
            switch (extension) {
                case "js":
                    return "text/javascript";
                case "woff":
                    return "application/font-woff";
                case "woff2":
                    return "application/font-woff2";
                case "ttf":
                    return "application/x-font-ttf";
                case "eot":
                    return "application/vnd.ms-fontobject";
                case "svg":
                    return "image/svg+xml";
                case "mp4":
                    return "video/mp4";
            }

            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        }
    }
}
CodeSmith
  • 1,621
  • 1
  • 13
  • 31
  • Unfortunately shouldOverrideUrlLoading is only called when you load a new web page, so it doesn't really fit my needs. I would like to intercept *all* requests. – Connor V Aug 09 '18 at 20:59
  • I tested it out and the header was only added to the request for the main web page. It was not added to any of the other requests for images, form submissions, etc. – Connor V Aug 09 '18 at 22:00
  • Sorry, I had the wrong webview, updated code with the webview that was working for me. You do need to use OKHttp or something to override the requests. The updated definition worked for me. – CodeSmith Aug 09 '18 at 22:26
0

As it turns out, my code actually works fine. The problem seems to be that the Chrome network inspector can't access request metadata for requests sent via HttpURLConnection (or anything besides the WebView itself), so my headers just didn't show up there. However, using this tool that I whipped up to display all request headers as json, I could see that they actually were delivered as intended.

Connor V
  • 11
  • 4