Configuration Guide

The concept of HttpClient configuration APIs is closely aligned with its Architecture layering principles. Configuration parameters are grouped by the architecture layer they apply to. Those groups of configuration parameters are modelled as immutable bean classes referred to as config beans. Config beans are safe to pass around to different classes as those beans cannot be modified at runtime.

A config beans class always represents logically related properties of a single architecture layer. There can be however properties shared by multiple layers applicable to the underlying connection or ongoing message exchange at a different points of their life-cycle. Socket timeout is one of such parameters. For example, connections can start off with a default value of the socket timeout which can later be overridden at a higher level or at a specific phase of connection life-cycle such as TLS handshake.

Configuration Levels

Network I/O Level

  • SocketConfig: these parameters apply to the Classic Network I/O layer and define connection socket properties.

    Socket configuration applies on a per-socket basis.

  • IOReactorConfig: these parameters apply to the Async Network I/O layer and define I/O reactor properties.

Protocol Transport Level

  • Http1Config: these parameters apply to the HTTP/1.1 protocol handlers and define common aspects of HTTP/1.1 message transmission.

    HTTP/1.1 configuration applies on a per-connection basis.

  • H2Config: these parameters apply to the HTTP/2 protocol handlers and define common aspects of HTTP/2 message transmission and message multiplexing.

    HTTP/2 configuration applies on a per-connection basis.

  • CharCodingConfig: these parameters apply to text based protocols such as HTTP/1.1 and define properties of binary to text coding.

    Character coding configuration applies on a per-connection basis.

Connection Management Level

  • ConnectionConfig: these parameters apply to connections managed by connection managers. Connection configuration is expected to work consistently across all supported network I/O implementations.

    Connection configuration applies on a per-route basis.

    An example of per-route connection configuration for the classic transport can be found here: classic and async.

TLS Level

  • TlsConfig: these parameters apply to connections at the time of TLS handshake execution and session negotiation. TLS configuration is expected to work consistently across all supported network I/O implementations.

    TLS configuration applies on a per-host basis.

    An example of per-host TLS configuration for the classic transport can be found here: classic and async.

Message Exchange Protocol Level

  • RequestConfig: these parameters apply to individual HTTP message exchanges. Request execution parameters are generally expected to work consistently to all HTTP protocol versions with a few exceptions when certain functionality is not applicable due to differences in message transport between different HTTP protocol versions.

    Request configuration applies on a per-request basis.

Caching Protocol Level

  • CacheConfig: these parameters apply to the caching protocol layer. They also define the most common properties shared by different cache storage implementations. Individual caching backends may still expose configuration options specific to those backends.

    Cache configuration applies on a per-instance basis.

Timeouts

The socket timeout is the only timeout that can be set at several configuration levels. All other timeouts apply to a single phase of connection management.

Timeouts by Phase

The table below lists the timeouts that apply to a request, in the order the request goes through them.

Phase Setting Default
Waiting for a connection from a pool RequestConfig connectionRequestTimeout 3 minutes
Host name resolution none -
TCP connect ConnectionConfig connectTimeout 3 minutes
TLS handshake TlsConfig handshakeTimeout the connect timeout
Request and response exchange the socket timeout, see Socket Timeout 3 minutes (classic), no timeout (async)
  • Host name resolution is done by the DnsResolver before the connect timeout starts. The system resolver applies its own timeouts.
  • The connect timeout applies to each resolved address separately. If a host name resolves to two addresses and neither of them responds, the connection attempt fails after twice the connect timeout.
  • If the TLS handshake timeout is not set, the connect timeout is used for the TLS handshake. Set the TLS handshake timeout explicitly if the handshake should time out differently from the TCP connect.
  • The deprecated RequestConfig connectTimeout, if set, takes precedence over the ConnectionConfig connect timeout.

Socket Timeout

The socket timeout is the maximum period of inactivity while waiting for data. It can be set at the following levels. A higher level replaces the value set at a lower level. The shorter value does not win: a response timeout of 3 seconds replaces a socket timeout of 1 second.

  1. Network I/O level: SocketConfig soTimeout for the classic transport (default: 3 minutes) or IOReactorConfig soTimeout for the async transport (default: no timeout).
  2. Connection management level: ConnectionConfig socketTimeout (default: not set). It is applied when a connection is created or leased from the pool.
  3. Message exchange protocol level: RequestConfig responseTimeout (default: not set). It is applied for the duration of a single message exchange.

None of these settings apply during the TLS handshake. The TLS handshake timeout is used instead.

Response timeout may be unsupported by HTTP transports with message multiplexing such as HTTP/2.

Timeouts Are Not Deadlines

The timeouts above limit how long the client waits for a single event. They do not limit the total time of a request.

  • The socket timeout limits inactivity. A response that keeps sending data slowly does not time out, even if it takes longer than the response timeout in total.
  • Connect attempts to multiple addresses and automatic request re-execution add up. Please make sure the automatic request re-execution policy has been configured appropriately.

To limit the total time of a request, use a timeout when waiting for the result, for example Future#get(long, TimeUnit), and cancel the request when it expires.