1_9_0.md

doc/release_notes/1_9_0.md

1.9.0

Features

:hedging plugin

The :hedging plugin implements a strategy called “request hedging”, whereby a request is sent two times, over different connections, and picking up whichever arrives first.

http = HTTP.plugin(:hedging)
http.get("http://www.example.com")
# sent two times, only the fastest one comes back...

You can read more about it in gitlab.com/os85/httpx/wikis/Hedging .

:proxy/http plugin: new options :proxy_headers and :enable_proxy_tunnel

The :proxy/http plugin (which gets automatically loaded by the :proxy plugin) gains two new options.

:proxy_headers

Can be passed a separate set of HTTP headers, which are going to be sent to the proxy when establishing the CONNECT proxy tunnel.

http = HTTPX.plugin(:proxy).with(proxy_headers: { "x-proxy-1" => "foo" }, headers: { "x-header-1" => "bar" }).get("https://example.com")
# -> CONNECT example.com HTTP/1.1
# -> Host: example.com
# -> X-Proxy-1: foo
# ...
# <- 200 OK
# ...
# -> GET / HTTP/1.1
# -> X-Headers-1: bar
# ...

:enable_proxy_tunnel

When set to true, it forces the establishment of a CONNECT proxy tunnel before sending the request. Bear in mind that this will be the norm for https:// requests, so only use this in cases where the requests are to be sent to an http:// URL and a CONNECT proxy tunnel is required.

Improvements

  • :request_timeout will also observe the connect phase, in case a request is sent to an idle connection. This means that, if you’re using :request_timeout, you no longer need to specify :connect_timeout.

  • The same will happen if you’re using :total_request_timeout.

  • do not require “io/wait” anymore for ruby 3.2 or higher.

  • :proxy/http plugin: raise a HTTPX::ConnectTimeoutError if there was a timeout error while waiting for the CONNECT request to complete.

Bugfixes

  • :auth plugin: fixed clause inverted check, which caused a new token to always be generated on retry.

  • :auth plugin: take auth_header_expires_at into account when deciding to regenerate on retry (token may have expired by the time the request will be retried).

  • :tracing plugin: fixed request initial time calculation in order to take into account the time to wait for a PING correctly.

  • :tracing plugin: fixed request initial time calculation for pending requests which were waiting for the connect phase and errored meanwhile.

  • :proxy/http plugin: :headers will not be sent anymore to the proxy when establishing the CONNECT proxy tunnel.

  • socket connect timeout bookkeeping is fixed, where in a multi request scenario, connect timeout errors shall not be raised too early if an error happens before the remainder of connections elapses.

  • :proxy plugin: allow proxy params to be frozen, which also fixes an issue where proxies identified as unhealthy by a previous request, would still be retried on for different hostnames.

  • :callbacks plugin: fix broken visibility of session close method.

  • native resolver: retry dns queries on not-imp and refused errors (treats them as transient resolver errors).

  • webmock adapter: fix emission of :response callback so that this only happens after the body is fully buffered (which makes the :callbacks plugin .on_response_completed callback works the same way when and when not stubbed).

  • :addresses: fix support for the documented variant where a hostname/ips hash is passed.

  • http2: fix interests calculation, so that:

  • a connection expects to read from connections which still have in-transit streams.

  • an HTTP/2 with no available flow control window in its streams will wait for incoming WINDOW_UPDATE frames.

  • http2: pause buffering the request body if there’s no available control window in the corresponding stream or connection.

  • http2: reset the ping timer too if a connection receives a GOAWAY frame while waiting for a PING to be ack’ed.

  • wait for read or write for any operation, considering that OpenSSL::SSL::SSLSocket objects may return both .wait_readable and :wait_writable for reads and writes.

  • when using :max_requests, also account for inflight requests when deciding to send it to the parser or the pending queue.

  • fixed HTTPX::Options#merge which was not freezing the resulting options object, something which happens when enabling plugins, which made resulting sessions unusable across Ractors.

  • fixed the Alt-Svc header parser to be able to parse values with multiple authorities.

  • fixed request params handling so that they are passed to all requests invoked (instead of only the first of them).

Chore

  • Emit a warning message whenever the connection is deactivated with pending requests; the message contains an internal state which should help debug it.