TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/cloudflare/pingora/llms.txt
Use this file to discover all available pages before exploring further.
upstream_peer() phase is where you tell Pingora exactly how to reach the upstream server for each request. You return a Box<HttpPeer>, and Pingora uses that to establish (or reuse) the connection, negotiate TLS, and configure every aspect of the transport. Because upstream_peer() is called per-request with full access to the request headers and your CTX state, you have complete freedom to implement any routing strategy — consistent hashing, round-robin, path-based routing, failover, or anything else.
HttpPeer Attributes
AnHttpPeer bundles the target address with all the connection-level metadata Pingora needs.
| Attribute | Type | Meaning |
|---|---|---|
address | SocketAddr | The IP address and port to connect to |
scheme | Scheme | Http or Https — controls whether TLS is used |
sni | String | The TLS Server Name Indication value (HTTPS only) |
proxy | Option<Proxy> | Tunnel the upstream connection through an HTTP CONNECT proxy |
client_cert_key | Option<Arc<CertKey>> | Client certificate and private key for mTLS connections |
options | PeerOptions | Detailed timeout, TLS, and transport configuration (see below) |
PeerOptions Reference
PeerOptions provides fine-grained control over how a connection is established and maintained.
| Field | Type | Meaning |
|---|---|---|
bind_to | Option<InetSocketAddr> | Local address to bind to as the outgoing client IP |
connection_timeout | Option<Duration> | Maximum time to wait for the TCP handshake to complete |
total_connection_timeout | Option<Duration> | Maximum time to wait for the full connection, including TLS handshake |
read_timeout | Option<Duration> | Maximum time to wait for each individual read() from upstream; resets after every read |
idle_timeout | Option<Duration> | How long an idle pooled connection is kept alive; set to 0 to disable pooling |
write_timeout | Option<Duration> | Maximum time allowed for a write() to the upstream to complete |
verify_cert | bool | Whether to validate the upstream server’s TLS certificate |
verify_hostname | bool | Whether to check that the server certificate’s CN/SAN matches the SNI |
use_system_certs | bool | Load and use the system trust store for certificate validation (s2n-tls only; has a performance cost) |
alternative_cn | Option<String> | Accept the server certificate if its CN matches this alternative name |
alpn | ALPN | Which HTTP protocol(s) to advertise during ALPN negotiation (HTTP/1.1, HTTP/2, or both) |
ca | Option<Arc<Box<[X509]>>> | Custom root CA(s) to use instead of the system trust store |
psk | Option<Arc<PskConfig>> | PSK configuration for PSK-TLS handshakes (s2n-tls only) |
s2n_security_policy | Option<S2NPolicy> | S2N security policy to use; defaults to default_tls13 (s2n-tls only) |
max_blinding_delay | Option<u32> | Maximum blinding delay in seconds applied on peer-triggered errors; default is 30 (s2n-tls only) |
tcp_keepalive | Option<TcpKeepalive> | TCP keepalive settings for the upstream connection |
http_upstream_request_policy | HttpUpstreamRequestPolicy | Controls automatic handling of hop-by-hop headers and HTTP/1 upgrade fields |
HTTP Upstream Request Header Policy
By default, Pingora strips downstream hop-by-hop request fields and any fields nominated by theConnection header before sending the request upstream. For HTTP/1 upstreams, if the request body is non-empty and neither Content-Length nor Transfer-Encoding is present after upstream_request_filter() runs, Pingora automatically adds Transfer-Encoding: chunked. Valid WebSocket upgrade handshakes are forwarded in a normalized form; other HTTP/1 upgrades are not forwarded by default.
When connection-nomination stripping is enabled, Pingora rejects requests where Connection nominates Host, X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto, or a pseudo-header-shaped field such as :authority. Requests with ten or more connection nominations are also rejected. These checks prevent silent removal of routing or request-origin metadata.
To preserve all hop-by-hop fields (RFC-non-compliant passthrough mode):
Connection while keeping all other default behavior:
strip_connection_nominated is enabled.
Examples
Basic HTTPS Peer
The most common case: connect to an upstream over HTTPS using a known IP and hostname for SNI.Basic HTTP Peer (No TLS)
Passfalse as the second argument to HttpPeer::new to connect over plain HTTP.
