HttpClient SSL Guide Oleg Kalnichevski $Id$

HttpClient can do HTTP over "Secure Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS) protocols provided the SSL support is properly installed and configured on the JVM level.

The following standard Java extensions are required:

Both JCE and JSSE have been integrated into the Java 2 platform as of version 1.4 and usually should not require any additional configuration in order to work with HttpClient.

With SSL properly set up and configured, secure HTTP communication over SSL should be as simple as plain HTTP communication.

HTTPS communication via an authenticating proxy server is also no different from plain HTTP communication. All the low-level details of establishing a tunneled SSL connection are abstracted away by HttpClient:

Per default HTTP client does not perform any custom certificate or certificate chain validation. The default HTTPS protocol implementation is completely reliant upon the standard functionality of the JSSE that comes with the JVM. If your application requires some additional processing of credentials such certificate verification or certificate chain validation, or you want to be using a third party SSL library, you can augment HttpClient to meet your specific requirements by providing a custom protocol implementation.

Implementation of a custom protocol involves the following steps:

There are several custom socket factories available in our contribution package. They can be a good start for those who seek to tailor the behavior of the HTTPS protocol to the specific needs of their application:

  1. Persistent SSL connections do not work on Sun's JVMs below 1.4

    Due to what appears to be a bug in Sun's older (below 1.4) implementation of Java Virtual Machines or JSSE there's no reliable way of telling if an SSL connection is 'stale' or not. For example, the HTTP 1.1 specification permits HTTP servers in 'keep-alive' mode to drop connection to the client after a given period inactivity without having to notify the client, effectively rendering such connection unusable or 'stale'. For the HTTP agent written in Java there's no reliable way known to us to test if a connection is 'stale' other than attempting to perform a read on it. If you happen to know a better way we would be delighted to hear about it. Rather unfortunately, a read operation on an idle SSL connection on Sun JVM older than 1.4 returns 'end of stream' instead of an expected read timeout. That effectively makes the connection appear 'stale' to the HttpClient, which leaves it with no other way but to drop the connection and to open a new one, thus defeating HTTP 1.1 keep-alive mechanism and resulting in significant performance degradation (SSL authentication is a highly time consuming operation). Sun's Java 1.4 SSL implementation does not exhibit this kind of problem. Plain sockets on all JVMs are not subject to the problem either.

    Workaround: If persistent SSL connections support is an issue for your application we strongly advise you to upgrade to Java 1.4.

  2. Non-preemptive authentication with a HTTPS server fails when connecting via a proxy

    This problem is caused by a serious flaw in HttpClient design and cannot be fixed without breaking the existing APIs. The problem will be addressed in HttpClient release 2.1.

    Workaround: Use preemptive server authentication. Please note that only BASIC authentication can be used preemptively. For more detailed information please refer to the Authentication Guide.

If you are unlucky and HTTPS with HttpClient does not work for you, it may be a bit premature to blame it squarely on HttpClient. The JSSE and JCE standard extensions are highly prone to all sorts of configuration problems, especially on older JVMs, which they are not an integral part of.

The application below can be used as an ultimate test that can reliably tell if SSL configured properly, as it relies on a plain socket in order to communicate with the target server. If you get an exception while executing this code, most certainly SSL is not functioning properly with your JVM. Please refer to Sun's official resources for support or additional details on JSSE configuration.