HttpClient Timeout

1. Overview

This tutorial will show how to setup the timeout on the Apache HttpClient.

2. Configure Timeouts via raw String parameters

The HttpClient comes with a lot of configuration parameters – and all of these can be set in a generic, map-like manner.

There are 3 timeout parameters to configure:

DefaultHttpClient httpClient = new DefaultHttpClient();

int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000);
httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout * 1000);
// httpParams.setParameter(ClientPNames.CONN_MANAGER_TIMEOUT, new Long(timeout * 1000));

A quick note is that the last parameter – the connection manager timeout – is commented out when using the 4.3.0 or 4.3.1 versions, because of this JIRA (due in 4.3.2).

3. Configure Timeouts via the API

The more important of these parameters – namely the first two – can also be set via a more type safe API:

DefaultHttpClient httpClient = new DefaultHttpClient();

int timeout = 5; // seconds
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeout * 1000); // http.connection.timeout
HttpConnectionParams.setSoTimeout(httpParams, timeout * 1000); // http.socket.timeout

The third parameter doesn’t have a custom setter in HttpConnectionParams, and it will still need to be set manually via the setParameter method.

4. Configure Timeouts using the new 4.3 Builder

The fluent, builder API introduced in 4.3 provides the right way to set timeouts at a high level:

int timeout = 5;
RequestConfig config = RequestConfig.custom()
  .setConnectTimeout(timeout * 1000)
  .setConnectionRequestTimeout(timeout * 1000)
  .setSocketTimeout(timeout * 1000).build();
CloseableHttpClient client = 
  HttpClientBuilder.create().setDefaultRequestConfig(config).build();

That is the recommended way of configuring all three timeouts in a type-safe and readable manner.

5. Timeout Properties Explained

Now, let’s explain what these various types of timeouts mean:

  • the Connection Timeout (http.connection.timeout) – the time to establish the connection with the remote host
  • the Socket Timeout (http.socket.timeout) – the time waiting for data – after the connection was established; maximum time of inactivity between two data packets
  • the Connection Manager Timeout (http.connection-manager.timeout) – the time to wait for a connection from the connection manager/pool

The first two parameters – the connection and socket timeouts – are the most important, but setting a timeout for obtaining a connection is definitly important in high load scenarios, which is why the third parameter shouldn’t be ignored.

6. Using the HttpClient

After being configured, the client can no be used to perform HTTP requests:

HttpGet getMethod = new HttpGet("http://host:8080/path");
HttpResponse response = httpClient.execute(getMethod);
System.out.println("HTTP Status of response: " + response.getStatusLine().getStatusCode());

With the previously defined client, the connection to the host will time out in 5 seconds, and if the connection is establised but no data is received, the timeout will also be 5 additional seconds.

Note that the connection timeout will result in a org.apache.http.conn.ConnectTimeoutException being thrown, while socket timeout will result in a java.net.SocketTimeoutException.

7. Hard Timeout

While setting timeouts on establishing the HTTP connection and not receiving data is very useful, sometimes we need to set a hard timeout for the entire request.

For example the download of a potentially large file fits into this category – in this case, the connection may be successfuly established, data may be consistently comming through, but we still need to ensure that the operation doesn’t go over some specific time threshold.

HttpClient doesn’t have any configuration that allow us to set an overall timeout for a request; it does however provide abort functionality for requests, so we can leverage that mechanism to implemet a simple timeout mechanism:

HttpGet getMethod = new HttpGet("http://localhost:8080/spring-security-rest-template/api/bars/1");

int hardTimeout = 5; // seconds
TimerTask task = new TimerTask() {
    @Override
    public void run() {
        if (getMethod != null) {
            getMethod.abort();
        }
    }
};
new Timer(true).schedule(task, hardTimeout * 1000);

HttpResponse response = httpClient.execute(getMethod);
System.out.println("HTTP Status of response: " + response.getStatusLine().getStatusCode());

We’re making use of the java.util.Timer and java.util.TimerTask to set up a simple delayed task which aborts the HTTP GET request after a 5 seconds hard timeout.

8. Conclusion

This tutorial discussed how to configure the various types of timeouts available for an HttpClient. It also illustrated a simple metchnism for hard timeout of an ongoing http connection.

The implementation of these examples can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about REST APIs and HTTP on Google+ - you can follow me there:

Free eBook REST Services with Spring
Join more than 2,500 engineers!

  • Biniam A.

    Great article! Thank you so much. I found all the answers I was looking for.

    • http://www.baeldung.com/ Eugen Paraschiv

      That particular section deals with the higher level API with which we can avoid using the raw property – mainly using HttpConnectionParams – your suggestion will work, but it’s not using the high level API. Additionally, that method is already described in Subsection 2.
      Thanks,
      Eugen.

Powered by WordPress. Designed by Woo Themes