package eftr2.dataservice2; import android.util.Log; import com.google.gson.Gson; import com.loopj.android.http.AsyncHttpClient; import com.loopj.android.http.AsyncHttpResponseHandler; import com.loopj.android.http.RequestParams; import org.apache.http.Header; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.StringEntity; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.net.UnknownHostException; import java.security.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; public abstract class BaseHttpClient { private static final String TAG = "eftr2.dataservice2.BaseHttpClient"; final static String JsonMIMEType = "application/json"; final static String USER_AGENT = "EFTRM"; private final static String ENCODING = "UTF-8"; private final IUserIdenityService identityService; private final AsyncHttpClient client; protected final Gson gson = new Gson(); private final String baseUri; public BaseHttpClient(String baseUri, IUserIdenityService identityService){ this.baseUri = baseUri; this.identityService = identityService; String login = this.identityService.getLogin(); String password = this.identityService.getPassword(); this.client = AsyncHttpClientFactory.getAsyncHttpClient(login, password); } /** * @param path - ресурс на бекенде * @param params - параметры GET запроса * @param onResponce - callback для функции * @throws UnsupportedEncodingException */ protected void GetAsync(String path, Map params, final ResponseHandler onResponce) { // валидация входных параметров if (path == null || path.length() == 0) throw new InvalidParameterException("Invalid pathAndQuery parameter"); if (params == null) params = new HashMap(); // отправляем запрос client.get( null, // android specific baseUri + path, // endpoint new RequestParams(params), getResponseHandler(onResponce)); } /** * @param path - ресурс на бекенде * @param model - модель объекта * @param onResponse - callback для функции * @throws UnsupportedEncodingException */ protected void PostAsync(String path, Object model, final ResponseHandler onResponse) { // валидация входных параметров if (path == null || path.length() == 0) throw new InvalidParameterException("Invalid pathAndQuery parameter"); if(model==null) model = new Object(); try { Log.d(TAG, "url = " + baseUri + path); client.post( null, baseUri + path, // endpoint new StringEntity(gson.toJson(model), ENCODING), // Body JsonMIMEType, getResponseHandler(onResponse)); } catch(final Exception e){ if(onResponse!=null){ onResponse.OnDone(new BaseResponse(true, "599", e.getMessage(), null)); } } } private AsyncHttpResponseHandler getResponseHandler(final ResponseHandler onResponce) { return new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { Log.i(TAG, ""); final boolean isFailed = statusCode > 300; onResponce.OnDone( new BaseResponse( isFailed, isFailed ? String.valueOf(statusCode) : null, null, responseBody ) ); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { Log.e(TAG, ""); final boolean isFailed = statusCode > 300; onResponce.OnDone( new BaseResponse( isFailed, String.valueOf(statusCode), isFailed ? error.getMessage() : null, responseBody ) ); } }; } } class AsyncHttpClientFactory { public static AsyncHttpClient getAsyncHttpClient(String login, String password){ AsyncHttpClient client = new AsyncHttpClient(); KeyStore trustStore = null; try { trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); final MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); client.setSSLSocketFactory(sf); } catch (Exception e) { throw new RuntimeException("Can't initiate client"); } client.addHeader("Accept", BaseHttpClient.JsonMIMEType); client.setBasicAuth(login, password); //этот метод НЕ работает с упреждающей посылкой basic auth хедера, он сначала пытается всё сделать без посыла авторизации, ожидая что его пошлют на авторизационный урл, и после этого он пошлёт авторизацию... //подробнее http://stackoverflow.com/questions/15110497/asynchttpclient-authentication-failed //так что тупо запихаем хедер руками //client.addHeader("Authorization", "Basic " + Base64.encodeToString((login+":"+password).getBytes(), Base64.NO_WRAP)); //client.setEnableRedirects(true); client.setUserAgent(BaseHttpClient.USER_AGENT); return client; } } class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } }