I’m using HttpClient for HTTPS requests, which has worked fine up until now. After upgrading to ICS, some users are reporting problems connecting on 3G connections.
EDIT: Most of them seem to be using a proxy, and I can reproduce this locally with a T-Mobile SIM using their proxy.
The logs have this stack trace:
java.lang.IllegalStateException: Scheme 'http' not registered.
org.apache.http.conn.scheme.SchemeRegistry.getScheme(SchemeRegistry.java:80)
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:126)
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
Our endpoint is HTTPS only, so we do not register a HTTP endpoint in our SchemeRegistry on purpose. There isn’t anywhere (AFAIK) where we redirect to HTTP.
Here is the code that sets up the HttpClient for the HTTPS client:
DefaultHttpClient ret = null;
// sets up parameters
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "utf-8");
params.setBooleanParameter("http.protocol.expect-continue", false);
HttpConnectionParams.setConnectionTimeout(params, DEFAULT_CONN_TIMEOUT_MSEC);
HttpConnectionParams.setSoTimeout(params, timeoutMsec);
HttpConnectionParams.setStaleCheckingEnabled(params, true);
SchemeRegistry registry = new SchemeRegistry();
final SocketFactory sslSocketFactory = getPreferredSSLSocketFactory();
registry.register(new Scheme("https", sslSocketFactory, 443));
ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
ret = new DefaultHttpClient(manager, params);
// for preemptive authentication
// http://dlinsin.blogspot.com/2009/08/http-basic-authentication-with-android.html
ret.addRequestInterceptor(preemptiveAuth, 0);
ret.setCookieStore(communalCookieJar);
SimpleCredentialsProvider credProvider = new SimpleCredentialsProvider(getAccountPreferences());
ret.setCredentialsProvider(credProvider);
return ret;
Note: We share this HttpClient instance among multiple threads.
The issue seemed to be that some carriers were pushing invalid proxy definitions with the 4.0.4 update. This broke HTTPS but HTTP worked properly (Google Play didn’t work, for instance).
One possible fix (besides fixing the invalid proxy entry) is to catch IllegalStateException when performing HttpClient requests and set a flag. This code will bypass any proxies: