[ruby-talk:444191] [ANN] httpx 0.23.0 released

httpx 0.23.0 has been released.


HTTPX is an HTTP client library for the Ruby programming language.

Among its features, it supports:

* HTTP/2 and HTTP/1.x protocol versions
* Concurrent requests by default
* Simple and chainable API
* Proxy Support (HTTP(S), CONNECT tunnel, Socks4/4a/5)
* Simple Timeout System
* Lightweight by default (require what you need)

And also:

* Compression (gzip, deflate, brotli)
* Streaming Requests
* Authentication (Basic Auth, Digest Auth, AWS Sigv4)
* Expect 100-continue
* Multipart Requests
* Cookies
* HTTP/2 Server Push
* H2C Upgrade
* Automatic follow redirects
* International Domain Names
* Circuit breaker
* WebDAV
* Datadog integration
* Faraday integration
* Webmock integration
* Sentry integration

Here are the updates since the last release:

# 0.23.0

## Features

### `:retries` plugin: resumable requests

The `:retries` plugin will now support scenarios where, if the request
being retried supports the `range` header, and a partial response has been
already buffered, the retry will resume from there and only download the
missing data.

#### HTTPX::ErrorResponse#response

As a result, ´HTTPX::ErrorResponse#response` has also been introduced;
error responses may have an actual response. This happens in cases where
the request failed **after** a partial response was initiated.

#### `:buffer_size` option

A new option, `:buffer_size`, can be used to tweak the buffers used by the
read/write socket routines (16k by default, you can lower it in
memory-constrained environments).

## Improvements

### `:native` resolver falls back to TCP for truncated messages

The `:native` resolver will repeat DNS queries to a nameserver via TCP when
the first attempt is marked as truncated. This behaviour is both aligned
with `getaddrinfo` and the `resolv` standard library.

This introduces a new `resolver_options` option, `:socket_type`, which can
now be `:tcp` if it is to remain the default.

## Chore

### HTTPX.build_request should receive upcased string (i.e. "GET")

Functions which receive an HTTP verb should be given the verb in "upcased
string" format now. The usage of symbols is still possible, but a
deprecation warning will be emitted, and support will be removed in v1.0.0 .

### Remove HTTPX::Registry

This momdule was a bit magical to use, difficult to debug, not thread-safe,
and overall a nuisance when it came to type checking. While there is the
possibility that someone was relying on it existing, nothing had ever been
publicly documented.

## Bugfixes

* fixed proxy discovery using proxy env vars (`HTTPS_PROXY`, `NO_PROXY`...)
being enabled/disabled based on first host used in the session;
* fixed `:no_proxy` option usage inn the `:proxy` plugin.
* fixed `webmock` adapter to correctly disable it when `Webmock.disable!`
is called.
* fixed a bug in `:digest_authentication` plugin when enabled and no
credentials were passed.
* fixed several bugs in the `sentry` adapter around breadcrumb handling.
* fixed `:native` resolver candidate calculation by putting absolute domain
at the bottom of the list.

# 0.22.5

## Bugfixes

* `datadog` and `sentry` integrations did not account for `Connection#send`
being possibly called multiple times (something possible for connection
coalescing, max requests exhaustion, or Happy Eyeballs 2), and were
registering multiple `on(:response)` callbacks. Requests are now marked
when decorated the first time.
* Happy Eyeballs handshake "connect errors" routine is now taking both name
resolution errors, as well as TLS handshake errors, into account, when the
handshake fails.

# 0.22.4

## Bugfixes

* fix happy eyeballs v2 bug where, once the first connection would be
established, the remaining one would still end up in the coalescing loop,
thereby closing itself via the `:tcp_open` callback.
* fix for faraday plugin parallel mode, where it'd hang if no requests
would be made in the parallel block (@catlee)

# 0.22.3

## Features

### HTTPX::Response::Body#filename

A new method, `.filename` can be called on response bodies, to get the
filename referenced by the server for the received payload (usually in the
"Content-Disposition" header).

response = HTTPX.get(url)
filename = response.body.filename
# you can do, for example:

## Improvements

### Loading integrations by default

Integrations will be loaded by default, as long as the dependency being
integrated is already available:

require "ddtrace"
require "httpx"

HTTPX.get(... # request will be traced via the datadog integration

### Faraday: better error handling

The `faraday` adapter will not raise errors anymore, when used in parallel
mode. This fixes the difference in behaviour with the equivalent `typhoeus`
parallel adapter, which does not raise errors in such cases as well. This
behaviour will exclude 4xx and 5xx HTTP responses, which will not be
considered errors in the `faraday` adapter.

If errors occur in parallel mode, these'll be available in `env[:error]`.
Users can check it in two ways:

response.status == 0
# or

## Bugfixes

* unix socket: handle the error when the path for the unix sock is invalid,
which was causing an endless loop.

### IPv6 / Happy eyeballs v2

* the `native` resolver will now use IPv6 nameservers with zone identifiers
to perform DNS queries. This bug was being ignored prior to ruby 3.1 due to
some pre-filtering on the nameservers which were covering misuse of the
`uri` dependency for this use case.
* Happy Eyeballs v2 handshake error on connection establishment for the
first IP will now ignore it, in case an ongoing connection for the second
IP is happening. This fixes a case where both IPv4 and IPv6 addresses are
served for a given domain, but only one of them can be connected to (i.e.
if connection via IPv6 fails, the IPv4 one should still proceed to
* the `native` resolver won't try querying DNS name candidates, if the
resolver sends an empty answer with an error code different from "domain
not found".
* fix error of Happy Eyeballs v2 handshake, where the resulting connection
would coalesce with an already open one for the same IP **before** requests
were merged to the coalesced connection, resulting in no requests being
sent and the client hanging.

## Chore

* fixed error message on wrong type of parameter for the
`compression_threshold_size` option from the `:compression` plugin.

# 0.22.2

## Chore

Checking response class before calling `.status`, as this was being called
in some places on error responses, thereby triggering the deprecation

# 0.22.1

## Bugfixes

* `:retries` plugin: fix `HTTPX::Response#response to point to the last
possible response in the redirection chain.
* `:stream` plugin: Make `HTTPX::Session#request` public (as it is in the
main class) .
* return 100 responses if the request didn't specifically ask for
"100-continue" negotiation (via the "expect" header).

## Improvements

Wrap low-level socket errors in a `HTTPX::ConnectionError` exception.