Last Update: 2024-05-14 15:30:12 +0000



Webmock Adapter

httpx can now be integrated with webmock, a popular HTTP requests stubbing library.

# minitest
require "webmock/minitest"
require "httpx/adapters/webmock"

# in rspec
require "webmock/rspec"
require "httpx/adapters/webmock"

# and now you're free for mocking
stub_http_request(:get, "https://www.google.com").and_return(status: 200, body: "here's google")

Read more about it in the webmock integration documentation.

Datadog Adapter

httpx ships with integration for ddtrace, datadog’s official tracing client. You just need to initialize it the following way:

require "ddtrace"
require "httpx/adapters/datadog"

Datadog.configure do |c|
  c.use :httpx

A trace will be emitted for every request, so this should be an interesting visualization if concurrent requests are sent.

Customization options and traces are similar to what the net-http adapter provides.

Read more about it in the datadog integration documentation.


Own multipart request encoder

httpx now ships with its own multipart formdata encoder, and does not rely on http-form_data anymore:

HTTPX.plugin(:multipart).post(uri, form: {file: File.new("path/to/file")})

Read more about it in the multipart plugin documentation, including also about why this was made.

Expect Plugin

The :expect plugin now works reliably when the server does not support the expect: 100-continue header, i.e. it’ll upload the body after a certain timeout. Building onn that, two behaviours are now implemented:

  • A cache of domains which did not respond to the expect header is now kept, so that subsequent requests can skip the timeout and immediately upload the payload.

  • If the “100 Continue” response arrives after the timeout expired and the body has been uploaded, the domain is removed from the cache, and subsequent requests will send the expect header.

SNI/Host options

Some extension of the API was applied in order to support custom TLS negotiation parameters. You can now pass :hostname under the :ssl options, and this will be used for the SNI part of the TLS negotiation. This is useful in scenarios where a proxy certificate doesn’t apply for the host one wants to send the request to:

response = session.get(proxy_ip, headers: { "host" => upstream_hostname }, ssl: { hostname: sni_hostname }


A default 5 second timeout is in-place when using the DNS :system resolver, as it was found out that. when using the resolv library, the DNS query will not be retried otherwise. You can change this setting py passing resolver_options: { timeouts: ANOTHER_TIMEOUT}. In the future, this may become another timeout option, however.