This is continuing from Stack Overflow.
When OkHttp tries a proxy in Android, and that route fails once, every request after that request will completely bypass the Android system proxy. So it is difficult to debug using Charles. Test case
@swankjesse replied that it's because that's how HttpUrlConnection behaves. UrlConnectionProxyTest
To repro:
I'm requesting the option to tell OkHttp to always use a proxy if there is one set.
Something like:
OkHttpClient.allowProxyBypass(boolean)
Aside from the nicer API, is this different from calling setProxy() on the OkHttpClient?
Probably just a nicer API. I feel like my work around is a little hacky. But it would be nice to have vetted code in the library as I found a bunch of questions online of how to solve this problem, but no solutions.
//Ask Android what proxies we have setup
List<Proxy> proxies = ProxySelector.getDefault().select(URI.create("http://www.somesite.com"));
if (proxies.size() > 0 && proxies.get(0) != Proxy.NO_PROXY) {
//Force OkHttp to always use the first proxy if found
baseClientBuilder.proxy(proxies.get(0));
}
I think your workaround is pretty reasonable, and this requirement is pretty specific. I’m going to icebox this and see if other people run into the same problem.
I'm also running into the same issue while trying to test timeout handling in my app. I'm using Charles Proxy to throttle network requests, but after the first request times out subsequent requests are no longer throttled, making testing very painful. :)
The proposed allowProxyBypass() method seems reasonable and could be set for debug builds.
I'm also running into the same issue. I put some URLs to the Black List of charles to test out how the app behaves when certain resources can't be loaded. However OkHttp just retries the request with no proxy, which defeats the purpose.
i also running into the same issue ,when i want to Charles to proxy, but no proxy
👍 on this issue
+1 to this.
I don't like the List<Proxy> proxies = ProxySelector.getDefault().select(URI.create("http://www.somesite.com")); too much. I don't think Android allows proxy per-uri but there is certainly a reason why the select() takes a uri as parameter.
Having a allowProxyBypass(boolean) removes all ambiguity.
If you’d like to force no proxy do this:
client = client.newBuilder()
.proxy(Proxy.NO_PROXY)
.build();
If you want to force a specific proxy, do this:
client = client.newBuilder()
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxyhost", 8888)))
.build();
I don't want any of those two options, I want to use the system wide proxy if defined.
It’ll do that by default! Unless that proxy is unreachable.
So what will be the behaviour of allowProxyBypass(false) if that proxy is unreachable ? I would like okhttp to return an error and not try something else.
@swankjesse:
" .. Unless that proxy is unreachable."
that is unwanted and unexpected behaviour.
Why would I want to bypass a system wide proxy in an app?
I expect the proxy settings to be respected by default.
Yes, because this is unexpected behavior an API method would be helpful for others to locate and resolve this issue.
👍 on this issue
I think I'll make a change to the default here. It’s an invasive change but I'm convinced that the cost of migration is worth the end goal of a more predictable API.
It is quite strange that a client does not respect the system settings as a user this completely blocks timeouts and other tests with custom proxies like charles.
Do you have a feeling for an ETA of this change?
Thank you Jesse!
Most helpful comment
I think I'll make a change to the default here. It’s an invasive change but I'm convinced that the cost of migration is worth the end goal of a more predictable API.