DefaultHttpClient hangs on execute() method in lollipop - android

In one of our old project we are using DefaultHttpClient for networking. its working fine below lollipop devices but in lollipop get request hangs execute method call.
We are creating HttpClient like this.
public static MyHttpClient createHttpClient(Context ctx) {
try {
if(mgr == null){
SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();
sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpParameters = new BasicHttpParams();
HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParameters, HTTP.UTF_8);
HttpConnectionParams.setConnectionTimeout(httpParameters, HOST_REACH_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, HOST_REACH_TIMEOUT);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
mgr = new ThreadSafeClientConnManager(httpParameters, registry);
}
return new MyHttpClient(mgr, httpParameters);
} catch (Exception e) {
return new MyHttpClient(ctx);
}
}
We are also setting timeouts. Any idea why its freezing there and how we can fix that?
Edit: one more thing that i have missed. It only happens when we hit same URL 3rd time. First two times it works fine.

Instantiate every time a new mgr.

Related

Use simple DefaultHttpClient or a keystore created with BouncyCastle bundled in the app

The server to which the app connected had a temporary certificate, or something like that. I am only taking care of the Android app and in order to make the https web service calls, the app used the unsafe implementation of the interface X509TrustManager. Now the server certificate has been fixed and has a final certificate.
The following code works:
HttpClient mHttpClient = null;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 30000);
DefaultHttpClient client = new DefaultHttpClient(httpParameters);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
mHttpClient = new DefaultHttpClient(mgr, client.getParams());
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
Basically, using this mHttpClient when making the web service calls does not rise any error or complaints and works as expected. However, I've seen implementations like this one which have a more secure approach.
My question is: by using the DefaultHttpClient simple as in the code above, could it rise some problems where on some devices the certificate may not be recognized as valid? Or better, should I go with the stored keystore as in the answer above?

How to reuse SSL session when I implement trust self-certificate in HttpClient?

I reference this page and implement trust slef-certificate as follows,
SchemeRegistry schemeRegistry = new SchemeRegistry();
// http scheme
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// https scheme
schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
HttpParams params = new BasicHttpParams();
params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
The EasySSLSocketFactory is here, and the EasyX509TrustManager is here.
I found that it would have a lot of SSL hello handshake.
After my studies, this situation may be reduced by using SSLSessionCache.
I search in the forum, but the solution almost using normal ssl connecting not using trust self-certificate.
How can I use SSLSessionCache when I implement trust self-certificate in HttpClient?

Single httpclient at same time accessed by two async task

I am using Single HTTP client for whole app to manage session on server side .
It works fine until two async task access same HTTP client at the same time.
I got this error .
"Invalid use of SingleClientConnManager: connection still allocated"
What to do in such situation. ?
You could create a custom HttpClient, that uses a ThreadSafeClientConnManager
public class MyGreatHttpClient extends DefaultHttpClient {
#Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
(...)
return new ThreadSafeClientConnManager(httpparams, registry);
}
}

connection pool shutdown android

I have a class for Httpclient. The same instance is used throughout the application. So if the client == null it should create one else it will return the existing instance. Everything works until i try to release the resource on exit by doing: client.getConnectionManager().shutdown();....after this i am not able to login again. It gives Sysem error saying : connection pool shutdown. Heres the class:
public class HttpClientFactory {
private static DefaultHttpClient client;
public synchronized static DefaultHttpClient getThreadSafeClient() {
if (client != null)
return client;
client = new DefaultHttpClient();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
HttpParams params = new BasicHttpParams();
SingleClientConnManager mgr = new SingleClientConnManager(params, schemeRegistry);
client = new DefaultHttpClient(mgr, params);
return client;
}
}
After this i simply run client.getConnectionManager().shutdown(); onBackPressed(), can somebody please help me
Ok..i got the solution...I was not setting it back to null and connection shutdown is suppose to be done in the same global class...
I have faced similar issue, but set
client.getConnectionManager().shutdown()
client.getConnectionManager() = null
could not resolved the problem.
Finally, I found out that, I did close all connections in onPostExecute, which is incorrect, so after moving them into doInBackground, it works.
Hope this helps someone!

Android ThreadSafeClientConnManager Timeouts?

I'm using a ThreadSafeClientConnManager to perform simultaneous requests in background threads on Android, set up with:
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager connman = new ThreadSafeClientConnManager(params, registry);
client = new DefaultHttpClient(connman, params);
And executing requests with (note that I'm using outh-signpost):
HttpGet request = new HttpGet("https://" + API_HOST + "/" + API_VERSION + path);
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(key, secret);
consumer.sign(request);
HttpResponse response = client.execute(request);
The problem is that after a while I start getting
java.net.SocketException: The operation timed out
Do I need to do something to explicitly release the connection after the request?
From the usage guide of apache httpclient, you need to make sure to consume all content on any pooled resource to guarantee it returns to the pool to be available for other threads later on -
http://hc.apache.org/httpcomponents-core-4.0.1/tutorial/html/fundamentals.html#d0e244
In case there's an exception thrown by the underlying library, it is best to abort the HttpMethod that you were trying to run, in which case the connection will be terminated.

Categories

Resources