I use static HttpClient and it works very slowly over https. I added -Djavax.net.debug = ssl and found that handshaking starts for every https request. it seems like he cannot reuse the old session, but I cannot find the reason.
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 ran into another problem on this host: "Fatal warning received: bad_record_mac", it was resolved by allowing only SSLv3
UPD1: HttpClient initialization 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 (Fatal alert issue issue: bad_record_mac)
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: the problem exists only for SSLv3, TLSv1 works fine