Open-Source Wikis

/

Envoy

/

Systems

/

Router

envoyproxy/envoy

Router

The router is the terminal HTTP filter — the one that turns a routed request into an upstream request. It lives in source/common/router/ (the implementation) and is wired in as a filter via source/extensions/filters/http/router/ (the factory).

Purpose

Given a request that has made it through every other HTTP filter, the router:

  1. Looks up the matching Route in the configured RouteConfiguration (or scoped/RDS-supplied one).
  2. Applies host rewrites, header mutations, and request-level features (timeouts, retries, hedging, mirrors).
  3. Picks an upstream HostDescription via the cluster manager's load balancer.
  4. Acquires an upstream connection from the appropriate connection pool.
  5. Forwards the request and streams the response back through the encoder filter chain.

Layout

File Role
router.cc (~2,600 lines) The Router::Filter HTTP filter — the per-request engine.
router.h Filter declaration plus FilterUtility helpers.
config_impl.h and config_impl.cc (~100k lines) The RouteConfiguration parser and matcher tree (virtual hosts → routes → clusters).
upstream_request.h and .cc The UpstreamRequest object representing a single attempt against an upstream host.
upstream_codec_filter.cc The terminal filter on the upstream filter chain.
retry_state_impl.cc Retry decisions (status codes, retry-on, retry budget).
shadow_writer_impl.cc Request mirroring.
rds_impl.cc, scoped_rds.cc, vhds.cc RDS, Scoped-RDS, and VHDS subscription glue.
router_ratelimit.cc Builds rate-limit descriptors from route metadata.

Key abstractions

Type Role
Router::Filter (router.h) The HTTP filter implementation; one per stream.
Router::ConfigImpl (config_impl.h) Parsed RouteConfiguration — vhosts, routes, retry policies.
Router::RouteEntryImplBase (config_impl.h) A single route entry: match, action, header mutations, retry policy, timeouts.
Router::UpstreamRequest (upstream_request.h) One in-flight attempt against an upstream — knows the connection pool, encoder, retry attempt index.
Router::RetryState (retry_state_impl.h) Per-stream retry decisions.
Router::ShadowWriter (shadow_writer_impl.h) Async fire-and-forget mirroring.

Path through Router::Filter::decodeHeaders

flowchart TD
    Start(decodeHeaders) --> Match[match route<br/>RouteConfiguration]
    Match -->|no match| LocalReply404[encodeHeaders 404]
    Match --> ClusterLookup[cluster_manager_.getThreadLocalCluster]
    ClusterLookup -->|no cluster| LocalReply503[encodeHeaders 503]
    ClusterLookup --> RewriteHost[host rewrite, header mutations]
    RewriteHost --> LB[cluster.loadBalancer().chooseHost]
    LB -->|no host| LocalReplyNoHealthy[encodeHeaders 503]
    LB --> CP[choose conn pool by protocol/transport]
    CP --> Send[UpstreamRequest::startUpstreamRequest]
    Send --> Codec[upstream codec encodes]

The same code path handles HTTP/1, HTTP/2, and HTTP/3 upstreams; the protocol comes from the cluster's ClusterInfo and dictates which connection pool family is used.

Retries

RetryStateImpl (retry_state_impl.cc) decides whether to retry, based on:

  • The route's retry_policy (e.g. 5xx, gateway-error, reset, retriable-headers, retriable-status-codes).
  • The x-envoy-retry-on, x-envoy-max-retries request headers.
  • A retry budget on the cluster.
  • A pluggable retry priority and host predicate (see source/extensions/retry/).

Each retry creates a fresh UpstreamRequest. Hedged requests run two UpstreamRequests in parallel, returning the faster.

Mirroring

When a route specifies request_mirror_policies, the router asks ShadowWriter to fire a copy of the request at the mirror cluster asynchronously. The mirror's response is discarded; only the primary affects the client. The mirror cluster runs through the full filter chain on the upstream side.

Internal redirects

If the upstream returns a 3xx and the route allows it, Router::Filter::handleInternalRedirect rewrites the request and re-enters the chain via decoder_callbacks_->recreateStream. The decision logic is pluggable via source/extensions/internal_redirect/.

Upstream filter chain

After upstream codec selection, a small upstream-side filter chain runs on the upstream Http::ConnectionPool::Instance. The terminal filter is UpstreamCodecFilter (upstream_codec_filter.cc), which writes the request onto the chosen codec. Custom upstream filters live in source/extensions/filters/http/upstream_codec/... style directories and are configured per-cluster.

Stream info enrichment

The router populates several fields on StreamInfo:

  • upstream_host_
  • upstream_local_address_
  • upstream_cluster_info_
  • route_name_, virtual_cluster_name_
  • attempt_count_ for retries

These are consumed by access loggers and stat sinks downstream.

Stats

The router emits per-cluster stats (counters for upstream_rq_2xx, upstream_rq_retry, upstream_rq_per_try_timeout, etc.) via a StatNames struct (router.h). Per-route stats (virtual_clusters, route_specific) require explicit configuration.

Integration points

  • HTTP connection manager. The router is one of the HTTP filters; without an HCM there is no router.
  • Cluster manager (cluster manager). The router calls getThreadLocalCluster per request.
  • Connection pools (connection pools). The router asks for a pool, then calls newStream.
  • xDS / RDS / VHDS / Scoped-RDS. Route configurations can be statically defined, RDS-pushed, or scoped (a key from the request selects which RouteConfig).
  • Tracing (tracing). The router sets the upstream span attributes.
  • Access logs. Final StreamInfo is emitted by the HCM after the router completes.

Entry points for modification

  • Adding retry semantics: read RetryStateImpl and the retry extensions.
  • Adding routing primitives (e.g. a new path matcher): the proto lives in api/envoy/config/route/v3/; the parser is in config_impl.cc.
  • Adding a request-level feature flag: usually a runtime guard in router.cc plus a new RetryPolicy/RouteAction field.
  • Replacing the upstream codec: implement a custom Upstream::UpstreamCodecFactory or wire in via UpstreamHttpFilterFactory.

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Router – Envoy wiki | Factory