/** * 2013 Foxykeep (http://datadroid.foxykeep.com) * <p> * Licensed under the Beerware License : <br /> * As long as you retain this notice you can do whatever you want with this stuff. If we meet some * day, and you think this stuff is worth it, you can buy me a beer in return */ package com.foxykeep.datadroid.network; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; /** * Helper method to choose the best available method to connect to the given URL. * <p/> * Current implementation try to use the following methods by descending order of priority: * - OkHTTP from Square * - HttpURLConnection from Android Framework */ public final class HttpUrlConnectionHelper { public static final String OKHTTP_HTTP_CLIENT_CLASS_NAME = "com.squareup.okhttp.OkHttpClient"; public static final String OPEN_METHOD_NAME = "open"; public static final String SET_SSL_SOCKET_FACTORY_METHOD_NAME = "setSslSocketFactory"; private HttpUrlConnectionHelper() {} /** * Open an URL connection using the best available method. * * @param url The URL to open. * @return A HttpURLConnection. */ public static HttpURLConnection openUrlConnection(URL url) throws IOException, KeyManagementException, NoSuchAlgorithmException { try { Class<?> okHttpClientClass = Class.forName(OKHTTP_HTTP_CLIENT_CLASS_NAME); Method openMethod = okHttpClientClass.getDeclaredMethod(OPEN_METHOD_NAME, URL.class); // Following block of code is needed to fix OkHttp issue // See https://github.com/square/okhttp/issues/184#issuecomment-18772733 for more info SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, null, null); Method setSslSocketFactoryMethod = okHttpClientClass.getDeclaredMethod( SET_SSL_SOCKET_FACTORY_METHOD_NAME, SSLSocketFactory.class); Object okHttpClientInstance = okHttpClientClass.newInstance(); setSslSocketFactoryMethod.invoke(okHttpClientInstance, sslContext.getSocketFactory()); // End of workaround fix return (HttpURLConnection) openMethod.invoke(okHttpClientInstance, url); } catch (InstantiationException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (IllegalAccessException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (ClassNotFoundException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (NoSuchMethodException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (IllegalArgumentException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (InvocationTargetException e) { // Nothing to do here. Fallback to standard url.openConnection() } catch (GeneralSecurityException e) { // Nothing to do here. Fallback to standard url.openConnection() } return (HttpURLConnection) url.openConnection(); } }