Dns Resolvers

The DNS resolver is a building block which the user can switch, or even enhance.

httpx ships with the following resolvers:

  • native: integrates with internal IO loop to resolve DNS queries.
  • system: uses the ruby resolv library to perform DNS queries.
  • https: performs DNS-over-HTTPS.

By default it’s using the native resolver. You can switch your DNS resolver by passing it as an option:

HTTPX.with(resolver_class: :https).get(....

or set HTTPX_RESOLVER environment variable in your environment to one of the possible values (ex: HTTPX_RESOLVER=https).

You can also pass additional DNS resolver options by using :resolver_options:

HTTPX.with(resolver_class: :https, resolver_options: {uri: "https://cloudflare-dns.com/dns-query", ...)

Native Resolver

The native resolver is a custom DNS resolver implementation integrated with the IO loop (it still uses the ruby resolv library to build the DNS packets). This way, DNS requests can also run concurrently in the same flow as the HTTP requests, and the former will not slow down the latter.

Resolver options

As :resolver_options, you can pass the same ones used for the ruby Resolv::DNS initializer (hint: check the options available for your ruby version).

System Resolver

This system resolver uses the resolv library to resolve DNS names. The resolution is blocking and therefore doesn’t integrate in a performant way. However, it’s a stable API, and in case that the native resolver needs some tweaks, one can always fall back to it.

Resolver options

As :resolver_options, you can pass the same ones used for the ruby Resolv::DNS initializer (hint: check the options available for your ruby version).

HTTPS Resolver

The HTTPS Resolver uses the DNS-over-HTTPS standard to perform DNS name resolution. It uses the already HTTP infrastructure to perform requests/responses, and therefore integrates well. It requires HTTP/2 support, so make sure that your ruby-openssl dependency supports ALPN negotiation.

Resolver options

By default, it uses the cloudflare dns endpoint (https://1.1.1.1/dns-query), but you can change it by setting up the :uri option in the :resolver_options (ex: HTTPX.with(resolver_class: :https, resolver_options: {uri: "https://dns.google.com/resolve"...).

The DNS requests use POST requests encoded as application/dns-message. You can however use GET requests by passing use_get: true in the resolver options.

Caveats

IPv4 resolution is the privileged record type, and IPv6 is the fallback. Because the world still sucks.

Next: Timeouts