I am trying to connect my Android (4.2) HTTP client to Jetty (9.1.3), using TLS 1.2 and with exchange of trusted certificates - server's is trusted on client's side, and client's is trusted on server's side. I am receiving a handshake and data is read by client but it takes up to 6 seconds. Some classes are from Apache HttpClient for Android 4.3.5 (GA).
Reading the key store (in Program class which extends Application):
private javax.net.ssl.SSLContext sslContext;
private org.apache.http.client.CredentialsProvider credentialsProvider;
public void createSSLContext(String pin) {
InputStream store = null;
try {
String password = getPassword();
store = getResources().openRawResource(R.raw.key_store);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(store, password.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, password.toCharArray());
trustFactory.init(keyStore);
String cn = null;
List<String> aliases = Collections.list(keyStore.aliases());
for (String alias : aliases) {
if (!alias.equalsIgnoreCase("server")) {
cn = alias;
break;
}
}
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), null);
credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(String.format("%s:%s", cn, pin)));
} catch (Throwable t) {
Log.e(Program.TAG, t.getMessage(), t);
throw new RuntimeException(t.getMessage(), t);
} finally {
if (store != null) {
try {
store.close();
} catch (IOException e) {
Log.e(Program.TAG, e.getMessage(), e);
}
}
}
}
public SSLContext getSSLContext() {
return sslContext;
}
public HttpContext getHttpContext() {
HttpClientContext httpContext = HttpClientContext.create();
httpContext.setCredentialsProvider(credentialsProvider);
return httpContext;
}
And a client class:
public final class Client {
private Context context;
public Client(Context context) {
this.context = context;
}
public void execute() {
Program program = (Program) context.getApplicationContext();
CloseableHttpClient client =
HttpClients.custom()
.setSSLSocketFactory(
new SSLConnectionSocketFactory(program.getSSLContext(), new AllowAllHostnameVerifier()))
.build();
HttpContext httpContext = program.getHttpContext();
CloseableHttpResponse response = null;
HttpEntity entity = null;
try {
HttpGet get = new HttpGet("https://10.1.5.195:8088/application/Application");
response = client.execute(get, httpContext);
entity = response.getEntity();
String r = EntityUtils.toString(entity);
System.out.println(r);
} catch (Throwable t) {
Log.e(Program.TAG, t.getMessage(), t);
} finally {
if (response != null) {
try {
response.close();
} catch (IOException e) {
Log.e(Program.TAG, e.getMessage(), e);
}
}
if (entity != null) {
try {
entity.consumeContent();
} catch (IOException e) {
Log.e(Program.TAG, e.getMessage(), e);
}
}
try {
client.close();
} catch (IOException e) {
Log.e(Program.TAG, e.getMessage(), e);
}
}
}
}
Android application is run on mobile device (Samsung Galaxy S3, Cyanogenmod 11). Both mobile device and server are in the same network (working on wi-fi).
When testing on AVD everything works fine.
What should I do to make it faster? I have tried to set http version 1.1 param, enable tcp no delay but it didn't change anything.
When using almost same classes in Java SE client, it takes about 400ms to receive data.