Updates the android target to use a version of HttpClient that is closer

to the version shipped with Android.  Also adds support for skipping SSL
certificate verifcation.  This allows the client to be used with self
signed certificates.

Conflicts:
	src/main/resources/android-java/apiInvoker.mustache
This commit is contained in:
Andrew Young 2014-01-08 14:30:10 -08:00
parent cf95d4e59e
commit 755591f9e5
2 changed files with 96 additions and 4 deletions

View File

@ -9,11 +9,18 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.http.*; import org.apache.http.*;
import org.apache.http.client.*; import org.apache.http.client.*;
import org.apache.http.client.methods.*; import org.apache.http.client.methods.*;
import org.apache.http.conn.*;
import org.apache.http.conn.scheme.*;
import org.apache.http.conn.ssl.*;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*; import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.*;
import org.apache.http.params.*;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import java.io.File; import java.io.File;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Map; import java.util.Map;
@ -22,15 +29,50 @@ import java.util.List;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class ApiInvoker { public class ApiInvoker {
private static ApiInvoker INSTANCE = new ApiInvoker(); private static ApiInvoker INSTANCE = new ApiInvoker();
private Map<String, String> defaultHeaderMap = new HashMap<String, String>(); private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private HttpClient client = null; private HttpClient client = null;
private boolean ignoreSSLCertificates = false;
private ClientConnectionManager ignoreSSLConnectionManager;
public ApiInvoker() {
initConnectionManager();
}
public static ApiInvoker getInstance() { public static ApiInvoker getInstance() {
return INSTANCE; return INSTANCE;
} }
public void ignoreSSLCertificates(boolean ignoreSSLCertificates) {
this.ignoreSSLCertificates = ignoreSSLCertificates;
}
public void addDefaultHeader(String key, String value) { public void addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value); defaultHeaderMap.put(key, value);
} }
@ -167,8 +209,58 @@ public class ApiInvoker {
} }
private HttpClient getClient(String host) { private HttpClient getClient(String host) {
if(client == null) if(client == null) {
client = new DefaultHttpClient(); if (ignoreSSLCertificates && ignoreSSLConnectionManager != null) {
// Trust self signed certificates
client = new DefaultHttpClient(ignoreSSLConnectionManager, new BasicHttpParams());
} else {
client = new DefaultHttpClient();
}
}
return client; return client;
} }
}
private void initConnectionManager() {
try {
final SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
TrustManager[] trustManagers = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}};
sslContext.init(null, trustManagers, new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory((KeyStore)null) {
private javax.net.ssl.SSLSocketFactory sslFactory = sslContext.getSocketFactory();
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
return sslFactory.createSocket(socket, host, port, autoClose);
}
public Socket createSocket() throws IOException {
return sslFactory.createSocket();
}
};
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme httpsScheme = new Scheme("https", sf, 443);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
ignoreSSLConnectionManager = new SingleClientConnManager(new BasicHttpParams(), schemeRegistry);
} catch (NoSuchAlgorithmException e) {
// This will only be thrown if SSL isn't available for some reason.
} catch (KeyManagementException e) {
// This might be thrown when passing a key into init(), but no key is being passed.
} catch (GeneralSecurityException e) {
throw new RuntimeException("Couldn't Init SSLSocketFactory: " + e.getMessage(), e);
}
}
}

View File

@ -207,7 +207,7 @@
<maven-plugin-version>1.0.0</maven-plugin-version> <maven-plugin-version>1.0.0</maven-plugin-version>
<junit-version>4.8.1</junit-version> <junit-version>4.8.1</junit-version>
<scala-test-version>1.6.1</scala-test-version> <scala-test-version>1.6.1</scala-test-version>
<httpclient-version>4.2.3</httpclient-version> <httpclient-version>4.0</httpclient-version>
<scala-maven-plugin-version>3.1.5</scala-maven-plugin-version> <scala-maven-plugin-version>3.1.5</scala-maven-plugin-version>
</properties> </properties>
</project> </project>