6

I am intercepting requests from the webview using shouldInterceptRequest

below is my code for returning my WebResourceResponse

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private static WebResourceResponse handleRequestViaUrlOnly(WebResourceRequest webResourceRequest){
        String url = webResourceRequest.getUrl().toString();
        Log.i("intercepting req....!!!", url);
        String ext = MimeTypeMap.getFileExtensionFromUrl(url);
        String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);

        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestProperty("Sample-Header", "hello");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            return new WebResourceResponse(mime, "UTF-8", conn.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

I call this method inside my CustomWebViewClient

class CustomWebViewClient extends WebViewClient {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        return handleRequestViaUrlOnly(request);
    }
}

However, when I check the Request Headers from the WebView remote debugger in chrome://inspect/#devices.

The additional RequestProperty that I added is not present.

conn.setRequestProperty("Sample-Header", "hello");

The Sample-Header is not present in the Request Headers in the WebView.

Am I missing something? I'll appreciate any help.

Aaron
  • 2,591
  • 4
  • 27
  • 45
  • Dose it goes in IO exception block? – Anurag Singh Feb 22 '17 at 07:48
  • nope it doesn't but calling this new URL(url).openConnection() requires catching the IOException. – Aaron Feb 22 '17 at 08:09
  • Just post the complete code of calling this method? – Anurag Singh Feb 22 '17 at 08:12
  • This is my complete code in intercepting url requests. – Aaron Feb 22 '17 at 08:15
  • handleRequestViaUrlOnly called from where that code. – Anurag Singh Feb 22 '17 at 08:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136321/discussion-between-anurag-singh-and-aaron). – Anurag Singh Feb 22 '17 at 08:32
  • WebResourceRequest request , The headers are present . please print and check for this value Log.d(TAG,"shouldInterceptRequest request "+request.getRequestHeaders()); – surya Feb 27 '17 at 15:40
  • @surya yes the headers are present when I log them, but in the webview, the headers are not present – Aaron Mar 01 '17 at 05:55
  • This [works for me](https://stackoverflow.com/a/66358447/192373). Maybe, you are below LOLLIPOP and the deprecated variant of the `shouldInterceptRequest` method is actually being invoked? Maybe, you catch an IOException and your `handleRequestViaUrlOnly()` returns **null**? – Alex Cohn Feb 24 '21 at 20:54

1 Answers1

1

So the problem is that when you are passing conn.getInputStream() it gives only data. Response headers could be extracted by conn.getHeaderFields(). Also you will not be able to get your extra header back unless server supports it and CORS not involved. Here is wireshark output of the connection

GET /~fdc/sample.html HTTP/1.1
Sample-Header: hello
Content-Type: application/x-www-form-urlencoded
User-Agent: Dalvik/2.1.0 (Linux; U; Android 7.1; Android SDK built for x86_64 Build/NPF26K)
Host: www.columbia.edu
Connection: Keep-Alive
Accept-Encoding: gzip
Content-Length: 0

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2017 09:06:58 GMT
Server: Apache
Last-Modified: Thu, 22 Apr 2004 15:52:25 GMT
Accept-Ranges: bytes
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 8664
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: text/html

As you can see there is no Sample-Header: hello header in response.

Here is the simple code that will construct WebResourceResponse headers from response and append your custom header to it:

webView.setWebViewClient(new WebViewClient() {
    private Map<String, String> convertResponseHeaders(Map<String, List<String>> headers) {
        Map<String, String> responseHeaders = new HashMap<>();
        responseHeaders.put("Sample-Header", "hello");

        for (Map.Entry<String, List<String>> item : headers.entrySet()) {
            List<String> values = new ArrayList<String>();

            for (String headerVal : item.getValue()) {
                values.add(headerVal);
            }
            String value = StringUtil.join(values, ",");
            Log.e(TAG, "processRequest: " + item.getKey() + " : " + value);

            responseHeaders.put(item.getKey(), value);
        }

        return responseHeaders;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        final String method = request.getMethod();
        final String url = request.getUrl().toString();
        Log.d(TAG, "processRequest: " + url + " method " + method);
        String ext = MimeTypeMap.getFileExtensionFromUrl(url);
        String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);

        try {
            HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection();
            conn.setRequestMethod(method);
            conn.setRequestProperty("Sample-Header", "hello");
            conn.setDoInput(true);
            conn.setUseCaches(false);

            Map<String, String> responseHeaders = convertResponseHeaders(conn.getHeaderFields());

            responseHeaders.put("Sample-Header", "hello");

            return new WebResourceResponse(
                    mime,
                    conn.getContentEncoding(),
                    conn.getResponseCode(),
                    conn.getResponseMessage(),
                    responseHeaders,
                    conn.getInputStream()
                    );

        } catch (Exception e) {
            Log.e(TAG, "shouldInterceptRequest: " + e);
        }
        return null;
    }
});
j2ko
  • 2,479
  • 1
  • 16
  • 29
  • I also have a code like this, yes I get the response headers and my problem is the request headers. I cannot add request headers to my webview. also if I log the request headers after adding one, I get them on the logs, however when it reaches the webview it is not present, – Aaron Mar 02 '17 at 03:08
  • So you are trying to modify webResourceReqest and what that change to be reflected on the javascript side in the webview? – j2ko Mar 02 '17 at 09:16