HTTP client for Apollo platform services.
[HttpClient] is a Tower Service: HTTP/1.1 and HTTP/2 over TCP and Unix
domain sockets. Configure via [HttpClientConfig].
Example
use ;
use Full;
use Bytes;
use ServiceExt;
#
# async
Protocol selection
HTTP/1.1 is the default. Set protocol: http2 when the server requires
HTTP/2, such as gRPC endpoints. Set protocol: alpn to negotiate the
version via the TLS handshake. Plain HTTP and unix:// connections have
no TLS and always use HTTP/1.1.
Unlike reqwest, which negotiates HTTP/1.1 or HTTP/2 automatically under
HTTPS, this client defaults to HTTP/1.1 and requires an explicit
[Protocol] setting for HTTP/2 or negotiation.
TLS
Configure trust anchors and client identity under tls. The example below
trusts a private CA bundle in addition to the OS native store and presents
a client certificate for mutual TLS:
tls:
# PEM bundle of CA certificates to trust. Multiple certificates may be
# concatenated. Loaded from disk via apollo-configuration file expansion.
certificate_authorities: ${file:./certs/internal-ca.pem}
# Trust the OS native certificate store in addition to the supplied CAs.
# Set false to trust only the supplied CAs (air-gapped environments).
use_native_certificate_store: true
client_authentication:
# PEM chain: leaf certificate followed by intermediates.
certificate_chain: ${file:./certs/client.pem}
# PEM-encoded unencrypted private key (PKCS#1, PKCS#8, or SEC1).
# Encrypted keys are not supported.
key: ${file:./certs/client.key}
Invalid PEM, empty bundles, encrypted keys, and configurations with no
trust anchors all fail at [HttpClient::new] with a dedicated
[HttpClientError] variant naming the offending field.
To supply a pre-built [rustls::ClientConfig] instead, for example, a
FIPS-compliant config or one backed by a custom certificate store, use
[HttpClient::builder]:
use Arc;
use ;
#
Unix domain sockets
On Unix targets, unix:// URIs dispatch over Unix domain sockets. Build the
request URI with [unix_uri]:
#
#
#
#
# async
HttpClientConfig::protocol selects HTTP/1.1 or HTTP/2 over the socket the
same way it does over TCP. ALPN has no TLS to negotiate over and falls back
to HTTP/1.1. Proxy configuration applies only to TCP.
On non-Unix targets, [HttpClient::new] still builds; sending a unix://
request returns [HttpClientError::UnsupportedScheme].
Metrics
Every request emits the following OpenTelemetry metrics:
| Metric | Description | Key attributes |
|---|---|---|
http.client.active_requests |
In-flight request count | method, server.address, server.port |
http.client.request.duration |
Request latency | method, server.address, server.port, protocol.version, status or error.type |
http.client.request.body.size |
Bytes sent (opt-in) | method, server.address, server.port, protocol.version, status |
http.client.response.body.size |
Bytes received (opt-in) | method, server.address, server.port, status |
http.client.open_connections |
Open connection gauge | server.address, server.port, protocol.version, http.connection.state |
http.client.connection.duration |
Connection lifetime | server.address, server.port, protocol.version |
For unix:// requests, server.address carries the socket path.
When a proxy is configured, connection-state metrics (http.client.open_connections,
http.client.connection.duration) also include network.peer.address and
network.peer.port, set to the proxy host and port.
All metrics also include url.scheme when telemetry.metrics.url_scheme is enabled.
Span attributes
Follows the OTel HTTP client span semantic conventions.
Always recorded:
http.request.method—_OTHERfor non-standard methods, with the original verb preserved inhttp.request.method_originalurl.fullserver.addressserver.port— absent forunix://http.response.status_codenetwork.protocol.versionerror.type— 4xx/5xx/transport
Opt-in (disabled by default, configure under telemetry.spans):
| Attribute | Setting |
|---|---|
url.scheme |
url_scheme |
http.request.body.size |
request_body_size |
http.response.body.size |
response_body_size |
user_agent.original |
user_agent |
network.transport |
network_transport (always "tcp") |
network.local.address |
network_local_address (static value, set at startup) |
network.local.port |
network_local_port (static value, set at startup) |
http.request.header.<name> |
request_headers |
http.response.header.<name> |
response_headers |
Not supported: url.template, http.request.size, http.response.size,
network.peer.address, network.peer.port, user_agent.synthetic.type.