I am using com.sun.net.httpserver.HttpsServer
in my current project which deals with client-authentification etc.. Currently it only prints out the clients address/port, so that I can check if one TCP-connection is used for multiple requests (keep-alive
) or if a new connection is established for every request (and thus a new SSL-handshake is made every time). When I use FireFox to make multiple request against the server I can see that keep-alive is working. So the server part works fine with GET and POST-requests.
If I use HttpURLConnection
to make a request against the Server (in this case using no SSL) keep-alive
works, too: Only one connection is established for multiple sequentially started requests.
But if I use HttpsURLConnection
(using exactly the same code, but using SSL) then keep-alive
is not working anymore. So for each request a new connection is established, although I am using the same SSLContext
(and SSLSocketFactory
):
// URL myUrl = ... // SSLContext mySsl = ... HttpsURLConnection conn = (HttpsURLConnection) myUrl.openConnection(); conn.setUseCaches(false); conn.setSSLSocketFactory(mySsl.getSocketFactory()); conn.setRequestMethod("POST"); // send Data // receive Data
How do I force HttpsURLConnection
to use keep-alive
because many requests will lead to many SSL-handshakes which is a real performance issue?
Update (2012-04-02): Instead of calling mySsl.getSocketFactory()
each time, I tried to cache the SSLSocketFactory
. But nothing changed. The problem still exists.
using HTTP/1.0, started to add an unofficial extension (to the protocol) named "keep-alive" in order to allow the reuse of a connection for multiple requests/responses. When the server receives this request and generates a response, if it supports keep-alive then it also adds the same above header to the response.
The Keep-Alive header is a general-type header. This header is used to hint at how the connection may be used to set a timeout and a maximum amount of requests. It can also be used to allow a single TCP connection to remain open for multiple HTTP requests/responses (default HTTP connection closed after each request).
The HTTP keep-alive header maintains a connection between a client and your server, reducing the time needed to serve files. A persistent connection also reduces the number of TCP and SSL/TLS connection requests, leading to a drop in round trip time (RTT).
Enabling Keep-Alive ensures that a single TCP connection is used to transfer multiple files from the server to the browser. This helps your page load faster as the browser doesn't need to establish multiple connections to retrieve all your page resources.
I ran into this exact same problem and finally have a solution after some in-depth debugging.
Http(s)UrlConnection does handle Keep-Alive by default but sockets must be in a very specific condition in order to be reused.
These are:
In the above code, the problem is:
conn.setSSLSocketFactory(mySsl.getSocketFactory());
Saving the result of getSocketFactory() to a static variable during initialization and then passing that in to conn.setSSLSocketFactory should allow the socket to be reused.
I couldn't get it working with HttpsUrlConnection
. But Apache's HTTP client handles keep-alive with SSL connections very well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With