Rewrite EVERY URL Resource of an Android WebView - android

I did not found an acceptable solution for rewriting all urls referenced in an WebView of an Android-App.
I mean all urls!
Not just those from HTTP-GET Methods. I also need to rewrite urls with HTTP-POST, PUT, DELETE, HEAD methods and urls inside Javascript(with all http methods).
Why I want to do this? I want to make an app, accessing intranet content from outside. Let's say intranet is located on https://myintranet.com
Let's say I have web resources https://myintranet.com/resources/whatever.html. If I am logged in my desktop-machine in the firm I can access the resource directly.
Now we want to go mobile. Therefore we do have a proxy, which supports https and basic authentication. We now accessing a resource with https://myproxy.com/myInternalMapperToIntranet/resources/whatever.html
What did I try:
I tried to set the Web view a WebViewClientoverriding
public WebResourceResponse shouldInterceptRequest (WebView view, String url)
look here Unfortunately this only works for HTTP-GET requests but not for HTTP POST requests.
And a WebViewClient overriding
public boolean shouldOverrideUrlLoading (WebView view, String url)
same thing here, HTTP Posts mapped to a send Button or JavaScript do not provoking a call to one of those methods.
In my case the most easiest way would be, to get the HttpClient of the WebView, and intercepting all requests this urls wants to make and rewriting the url to the one with the Proxy-content.
I simply could define a regex and replace the Url. But it seems, this is not possible in Android. A Collegue did this on a iOS-App, but on Android it seems currently not possible. I found a possible solution #API 21 with:
public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
the WebResourceRequests encapsulates the Http Method, so it smells for the possibility to intercept all httpMethods. Unfortunately I have to support API 17, and may not use this API.
I cant believe that this technical requirement cant be realized with standard android components. Please prove me the opposite!
Does anybody knows alternatives?
Doing the whole rewriting in the back-end for many simultaneous users is currently no alternative. It has to be done client-side on the App due performance issues.
TIA Luke

Related

Does android create connections for each http request?

To show a website, you need to fetch html + multiple js/css files.
Does android open connection for each file (URI)?
I'm about to do it (opening connection for each file) and want to know if this is absurdly stupid.
What I want to eventually do is to cache js/css files myself (I'm considering inside shouldInterceptRequest(WebView view, WebResourceRequest request) )
I tried to see how android itself does it by breaking at the shouldInterceptRequest function, but I couldn't find much more info from there.
Does android open connection for each file (URI)?
If you are referring to inside WebView, that will be dictated by the version of WebView that you are using. Keep-alive support (and SPDY/HTTP2) should be supported today; I don't know how far back the SPDY/HTTP2 support would go.
I'm about to do it (opening connection for each file) and want to know if this is absurdly stupid
If you mean that you are going to make HTTP requests yourself outside of WebView, choose an HTTP client API that supports keep-alive and SPDY/HTTP2. Note that keep-alive itself only works on non-SSL connections, and you are using SSL (right? right?!?), so SPDY/HTTP2 support is more critical. OkHttp offers this, to the point where HttpUrlConnection on Android 4.4+ is actually using OkHttp under the covers. Other HTTP client libraries may offer it as well.

How to inspect HTTP requests made by WebViews

As you know, a lot of request (images, scripts, AJAX, etc.) are send when loading a single page. So I need to get all those request and inspect them.
So the question would be: How can I inspect the HTTP requests that are made when a WebView loads a page ?
I want: headers, method, status code, response, cookies.
Right now, I have:
public void onLoadResource(WebView view, String url){
Log.d("my-tag", "onLoadResource = " + url );
}
But that only shows me the URL.
The best you can get in your app is the WebViewClient.shouldInterceptRequest method, but that only has the URL. You currently can't get any of the things you've listed.
For debugging you can use Chrome DevTools if you're using Android 4.4.
Look here: https://gist.github.com/kibotu/32313b957cd01258cf67 where you get the http headers at android >=21
The easiest way is to use a proxy. I use Charles, but I'm sure there are others. On the device, go to the WiFi settings, long click the one you're connected to, select "modify network" and enable the advanced options. There you'll be abel to configure the proxy settings for the whole device.

Android get request and response objects from webview

is there a way to get request and response objects from a webview?
for requests made from some webpage running in my webview, i want to intercept the full http request object(the headers, http method used, http body etc) and divert and send across that request into another channel.
For responses received from the webview, i want to do the same and get the object and its properties.
So far i have looked at the webviewClient android class which allows you to intercept url links executed by a webpage and intercept the resources it loads.
However, what i want to intercept, is any actual http requests the webpage makes. is this possible in Android webview?
thanks
That is not directly possible. You are welcome to write an HTTP proxy, then attempt to get WebView to work with that (e.g., see if it supports the http.proxyHost and http.proxyPort system properties).

Android WebView HTML with cookies

I am trying to pull HTML data out of a WebView. I've seen this done a thousand times and I've even gotten it to work myself. However, my new project leads to an interesting situation: I need to login to a site through a WebView and then pull the HTML. Obviously, the Socket method doesn't work, because in order for a webpage to be returned you need the cookie for authentication. I've also tried the JavascriptInterface trick, but that didn't work either. I'm thinking the best way to achieve this is to use HttpGet with CookieManager? Does anyone know how I can get raw HTML code from a WebView with an auth cookie? Thanks!
EDIT: I did some JS injection and didn't see any cookies... so it might not be a cookie issue? But the links that you get redirected to are generic, like mainPage?a=1 and infoPage. You cannot simply copy/paste the links into another browser you have to be logged in to view these links. For those of you who are web experts, you may know an easy solution.
WebView isn't really meant for getting HTML for programmatic use, the idea is that it's just a direct window to a URL for user interaction.
To get what you want, you can use a java.net.HttpURLConnection with a CookieManager, it's worked fine for me on Android and it's suggested in the Android SDK docs:
// in an activity's onCreate:
cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
// later on
void getAPage(URL url) {
HttpURLConnection huc = (HttpURLConnection) url.openConnection();
System.out.println("hello from huc, response code is: " + huc.getResponseCode());
// huc.getInputStream() gives you the content.
}
The CookieManager will persist all cookies through the lifetime of the application without you having to do anything extra. You can make posts with HttpURLConnection too.

Silently authentication from webview

Here's what I want to have figured out : I'm using a webview to access a feature of a site that requires authentication. Therefore whenever that particular link is loaded the login page is displayed . Is is possible to somehow authenticate silently so that the particular feature is displayed directly ? Perhaps by using the "webView.setHttpAuthUsernamePassword" (which does not seem to work for me, or I don't do it right) or by making some POST or GET before I load the page , or other possibility ?
On logging in the server is simply supposed to send me a cookie.
That method only works for HTTP Basic Auth, not for form-based login.
Your best bet would be to use the onLoadResource method of the WebViewClient to detect that the page is about to load, then override the content of the WebView using loadData with a chunk of HTML/js that posts to the login form with the proper parameters, then detect the successful cookie return and forward on to the original url.
Depending on the site it may be messy: you may have to set the proper referer headers or CSRF tokens and other things of that nature.
Good luck.
See, you could do the task this way, I am not sure if this is what you want:
#Override
public void onReceivedHttpAuthRequest(
WebView view,
HttpAuthHandler handler,
String host,
String realm) {
String currentUrl = yourWebView.getUrl();
if(currentUrl.equals("www.yourwebsite.com")){
handler.proceed("username","password");
}
}

Categories

Resources