I use static HttpClient, and it works very slowly over https. I have added -Djavax.net.debug=ssl and found that handshaking is started for every https request again. looks like it can not reuse old session, but I can not found why.
9007199254743735, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
9007199254743735, setSoTimeout(0) called
%% No cached client session
*** ClientHello, SSLv3
...
%% Didn't cache non-resumable client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
...
Is initial handshake: true
BTW. before I was faced with another problem on this host: "Received fatal alert: bad_record_mac", it was solved by allowing only SSLv3
UPD1: HttpClient init code
final SSLContext sslCtx;
sslCtx = SSLContext.getInstance("SSL");
sslCtx.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] cert,
String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] cert,
String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}}, null);
X509HostnameVerifier verifier = new X509HostnameVerifier() {
@Override
public void verify(String string, SSLSocket ssls) throws IOException {
}
@Override
public void verify(String string, X509Certificate xc) throws SSLException {
}
@Override
public void verify(String string, String[] strings, String[] strings1) throws SSLException {
}
@Override
public boolean verify(String string, SSLSession ssls) {
return true;
}
};
final SSLSocketFactory socketFactory = new SSLv3SocketFactory(sslCtx, verifier);
final SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, socketFactory));
final PoolingClientConnectionManager cm = new PoolingClientConnectionManager(registry);
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(50);
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(httpParams, timeout);
httpClient = new DefaultHttpClient(cm, httpParams);
((DefaultHttpClient) httpClient).setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse hr, HttpContext hc) {
return 0;
}
});
httpClient.getParams().setParameter("http.socket.timeout", 900000);
UPD2: modified SSLSocketFactory("Received fatal alert: bad_record_mac" issue)
public class SSLv3SocketFactory extends SSLSocketFactory {
private final javax.net.ssl.SSLSocketFactory socketfactory;
public SSLv3SocketFactory(SSLContext sslContext, X509HostnameVerifier hostnameVerifier) {
super(sslContext, hostnameVerifier);
this.socketfactory = sslContext.getSocketFactory();
}
@Override
public Socket createLayeredSocket(
final Socket socket,
final String host,
final int port,
final boolean autoClose) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
socket,
host,
port,
autoClose);
sslSocket.setEnabledProtocols(new String[]{"SSLv3"});
return sslSocket;
}
@Override
public Socket connectSocket(
final Socket socket,
final InetSocketAddress remoteAddress,
final InetSocketAddress localAddress,
final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
if (socket instanceof SSLSocket) {
((SSLSocket) socket).setEnabledProtocols(new String[]{"SSLv3"});;
}
return super.connectSocket(socket, remoteAddress, localAddress, params);
}
}
UPD3: Problem exists only for SSLv3, TLSv1 works fine