The timeouts supported are:
:connect_timeout
:write_timeout
:read_timeout
:request_timeout
:operation_timeout
:keep_alive_timeout
The can be passed as an extra option to the session:
HTTPX.with(timeout: { operation_timeout: 15 }).get("https://google.....")
Timeouts which expire will trigger an error of the HTTPX::TimeoutError
type.
The :connect_timeout
covers the time it takes to establish a TCP connection, and in case it’s a TLS connection, the time it takes to establish a TLS connection.
Timeout expires raise a HTTPX::ConnectionTimeoutError
exception, which subclasses HTTPX::TimeoutError
.
Note: This timeout does not cover the time it takes to perform the DNS hostname resolution.
The :write_timeout
covers the total time it takes to fully send an HTTP request to the server.
Timeout expires raise a HTTPX::WriteTimeoutError
exception.
The :read_timeout
covers the total time it takes to fully read an HTTP response from the server.
Timeout expires raise a HTTPX::ReadTimeoutError
exception.
(Note: the :stream
plugin removes this default, in order to support endless responses.)
The :request_timeout
covers the total time it takes to send an HTTP request and read its response fromm the server.
You can use it to combine the 2 timeouts above into 1, and don’t care that much about knowing whether the request failed on writing or reading.
Timeout expires raise a HTTPX::RequestTimeoutError
exception.
The :operation_timeout
is used when waiting for read/write interests on the TCP connection.
Contrary to the timeouts above, which are deadline oriented, :operation_timeout
is used for the individual socket operations, so overall request/response turnaround time may still be quite high, given slow servers can still take advantage of it. If this is important to you, consider using :read_timeout
or :write_timeout
instead.
Timeout expires raise a HTTPX::TimeoutError
exception.
(Note: the :stream
plugin sets this timeout to 60 seconds.)
The :keep_alive_timeout
is the time after last use of a connection (if the connection is persistent) that httpx
will consider it to be reused for subsequent requests . This timeout is reset after every new request on that connection. If the timeout expires when sending a request for the same origin, one of two things will happen:
PING
frame will be sent on the connection to check availability of the connection; if still available, it will be reused, otherwise a new connection will be opened.Most other libraries only support HTTP/1.1 , which means there’s a direct mapping between the TCP operation to the HTTP interaction (i.e. a read timeout implies one failed reading the HTTP response). This is not true anymore with HTTP/2, where successive socket reads/writes happen during a single HTTP interaction. This leads to confusion, hence why it was replaced by a single op timeout, :operation_timeout
, applicable to both socket reads and writes.
:write_timeout
, :read_timeout
and :request_timeout
are deadline-oriented, in that they meter the time waiting to flush the request to the server, or fully getting a response, or both. This fits the purpose of an HTTP client better, as one doesn’t need to know about which socket, if any, is being used, and it is also less exposed to slow servers of the “dripping” kind.
Resolver options are passed as :resolver_options
, as a hash. The right answer depends of which resolver you’re using:
You can pass a :timeouts
to the :resolver_options
hash, which is documented in the ruby documentation.
As the native resolver reuses the same system resolver options API, the suggestion above still stands.
As the DNS connection is an HTTP(S) connection, all of the above timeouts are to be reused.
Next: Connections