/* Swisscom Safe Connect Copyright (C) 2014 Swisscom This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.swisscom.safeconnect.backend; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import com.swisscom.safeconnect.BuildConfig; import com.swisscom.safeconnect.model.RawResponse; import com.swisscom.safeconnect.utils.Config; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.ref.WeakReference; import java.security.KeyStore; public class PlumberTask extends AsyncTask<InternalCallback, Void, InternalCallback> { private WeakReference<Context> context; private int httpTimeout = 10000; private static KeyStore keyStore; private static SSLSocketFactory sslSocketFactory; private static SchemeRegistry schemeRegistry; private static final Object mKeystoreLock = new Object(); public PlumberTask(Context context) { this.context = new WeakReference<Context>(context); } public PlumberTask() { this.context = null; } /** * Used to run the AsyncTasks in a ThreadPool. Otherwise all AsyncTasks will be exectued sequentially, * this sometimes resulted in problems when a previous task did not finish (in time). * * @param taskCallback */ public void execute(InternalCallback taskCallback){ super.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, taskCallback); } @Override protected InternalCallback doInBackground(InternalCallback... params) { if (params.length > 0) { HttpRequestBase request = params[0].getHttpRequest(); RawResponse response = doSyncRequest(request); params[0].setResponse(response); return params[0]; } else { return null; } } @Override protected void onPostExecute(InternalCallback callbackResult) { if (callbackResult != null) { callbackResult.onRequestComplete(); } } private static String inputStreamToString(InputStream is) throws IOException { StringBuilder sb = new StringBuilder(); InputStreamReader isr = new InputStreamReader(is); BufferedReader rd = new BufferedReader(isr); try { String line; while ((line = rd.readLine()) != null) { sb.append(line); } } finally { rd.close(); isr.close(); is.close(); } return sb.toString(); } public void setHttpTimeout(int ms){ httpTimeout = ms; } public static HttpClient getNewHttpClient(Context context, HttpParams params) { InputStream is = null; try { synchronized (mKeystoreLock) { if (keyStore == null) { is = context.getAssets().open("swisscom.bks"); keyStore = KeyStore.getInstance("BKS"); keyStore.load(is, "sw1ssc0m".toCharArray()); } if (sslSocketFactory == null) { sslSocketFactory = new SwisscomSslSocketFactory(keyStore); sslSocketFactory.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); } if (schemeRegistry == null) { schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", sslSocketFactory, 443)); } HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, "UTF-8"); } ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, schemeRegistry); return new DefaultHttpClient(ccm, params); } catch (Exception e) { if (BuildConfig.DEBUG) Log.e(Config.TAG, "error", e); return new DefaultHttpClient(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { if (BuildConfig.DEBUG) Log.e(Config.TAG, "error", e); } } } } public RawResponse doSyncRequest(HttpRequestBase request) { HttpParams httpParams = new BasicHttpParams(); if (httpTimeout > 0) { HttpConnectionParams.setConnectionTimeout(httpParams, httpTimeout); HttpConnectionParams.setSoTimeout(httpParams, httpTimeout); } HttpClient client = null; if (context != null) { Context ctx = context.get(); if (ctx != null) { client = getNewHttpClient(ctx, httpParams); } } if (client == null) { client = new DefaultHttpClient(); } RawResponse response = new RawResponse(); try { HttpResponse httpResponse = client.execute(request); int statusCode = httpResponse.getStatusLine().getStatusCode(); if (BuildConfig.DEBUG) Log.d(Config.TAG, "Request to " + request.getURI().toString() + " --> " + httpResponse.getStatusLine()); // get the body String json = inputStreamToString(httpResponse.getEntity().getContent()); response.status = statusCode; response.body = json; } catch (IOException e) { if (BuildConfig.DEBUG) Log.e(Config.TAG, "Request to " + request.getURI().toString() + " --> FAIL", e); response.status = 0; response.body = null; } return response; } }