Open-Source Wikis

/

Envoy

/

Systems

/

HTTP connection manager

envoyproxy/envoy

HTTP connection manager

The HTTP connection manager (HCM) is the network filter that turns a TCP (or QUIC) connection into a stream of HTTP requests, runs them through the L7 filter chain, and writes responses back. It is implemented as a network filter so it can plug into the standard listener pipeline, but it is the largest single component in Envoy and the entry point to almost all interesting L7 behaviour.

Purpose

For each connection routed to it, the HCM:

  1. Picks an HTTP/1, HTTP/2, or HTTP/3 codec based on the configured protocol or ALPN.
  2. Drives the codec to parse incoming bytes into headers/body/trailers.
  3. Per request, instantiates a fresh FilterManager and runs the configured chain of HTTP filters.
  4. Manages timeouts (idle, request, stream), local replies, draining, GOAWAY, and overload signals.
  5. Generates request access logs and tracing spans.

Operator documentation is at envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/http_conn_man.

Layout

The HCM is split between a network-filter shim and the implementation in source/common/http/:

File Role
source/extensions/filters/network/http_connection_manager/config.cc Network filter factory: parses HttpConnectionManager proto, builds filter chain factories, instantiates ConnectionManagerImpl.
source/common/http/conn_manager_impl.h and .cc The ConnectionManagerImpl class — the engine.
source/common/http/filter_manager.h and .cc The L7 filter execution engine, used per-stream.
source/common/http/conn_manager_utility.cc Helpers for populating request-id, x-forwarded-*, internal/external request classification.
source/common/http/conn_manager_config.h The ConnectionManagerConfig interface that the filter chain queries.
source/common/http/http1/, http2/ The HTTP/1.1 and HTTP/2 codecs (HTTP/3 codec is in source/common/quic/).

conn_manager_impl.cc is the second-largest single file in the project at ~2,600 lines.

Key abstractions

Type Role
ConnectionManagerImpl The network filter. Owns the codec and a list of in-flight streams.
ActiveStream (inside conn_manager_impl.h) Per-request state: request/response headers, decoder/encoder filter chains, timers.
FilterManager (filter_manager.h) Runs the decoder filter chain, then encoder, then trailers/data callbacks.
ConnectionManagerConfig Read-only config the HCM consults — route configuration, tracing, access loggers, idle timeout, etc.
ServerConnection (envoy/http/codec.h) Codec interface; one of Http1::ServerConnection, Http2::ServerConnection, Http3::ServerConnection.
Filter (envoy/http/filter.h) The L7 filter base interface (decoder + encoder + trailers + on-destroy).

Lifetime of a request

sequenceDiagram
    participant N as Network filter chain
    participant HCM as ConnectionManagerImpl
    participant Codec as ServerConnection (h1/h2/h3)
    participant FM as FilterManager
    participant DF as Decoder filters
    participant R as Router
    participant U as Upstream
    participant EF as Encoder filters

    N->>HCM: onData(buffer)
    HCM->>Codec: dispatch(buffer)
    Codec->>HCM: newStream
    HCM->>FM: create FilterManager + ActiveStream
    Codec->>FM: decodeHeaders / decodeData / decodeTrailers
    FM->>DF: run decoder chain
    DF->>R: terminal filter (router)
    R->>U: routerNewStream → upstream conn pool
    U-->>R: response
    R->>FM: encodeHeaders / encodeData / encodeTrailers
    FM->>EF: run encoder chain
    EF->>Codec: write response
    Codec->>N: onWrite (response bytes)

The flow is similar across protocols. HTTP/1 has at most one active stream per connection (with optional pipelining); HTTP/2 multiplexes many streams; HTTP/3 multiplexes streams over QUIC datagrams. The codec abstracts the differences and the FilterManager is identical regardless.

Codec selection

ConnectionManagerImpl::onData lazily creates a codec on the first byte:

  • For HTTP/3, the QUIC layer creates the codec at connection time — onConnection triggers codec creation.
  • For HTTP/1 and HTTP/2 the codec is selected from HttpConnectionManager.codec_type. With AUTO, ALPN selects HTTP/2 or HTTP/3, and the first request line on the wire selects HTTP/1 vs HTTP/2 (the PRI preface).

The codec receives bytes and calls back into HCM with structured events (newStream, decodeHeaders, etc.).

Filter chain

The per-stream filter chain is constructed by a FilterChainFactory built at config time. Each filter's decodeHeaders is called in declared order; encoder filters run in reverse order. Filters can:

  • Continue iteration immediately, returning FilterHeadersStatus::Continue.
  • Stop iteration and resume later: StopIteration, then call decoder_callbacks_->continueDecoding().
  • Generate a local reply and short-circuit the chain.
  • Modify headers, body, or trailers.
  • Make outbound requests via the async client (e.g. ext_authz).

The terminal decoder filter is the router, which selects a cluster, picks a host, and forwards the request.

Headers and body buffers

Headers are stored in Http::HeaderMapImpl (source/common/http/header_map_impl.cc) — a custom container that interns common header names via the symbol table. Bodies use Buffer::WatermarkBuffer (source/common/buffer/watermark_buffer.cc) which signals back-pressure when high watermarks are reached.

Timeouts

The HCM enforces a layered set of timeouts:

Timer Configured by Purpose
request_timeout HttpConnectionManager.request_timeout Cap on receiving the entire request from the downstream client.
request_headers_timeout HttpConnectionManager.request_headers_timeout Cap on receiving just the request headers.
idle_timeout HttpConnectionManager.common_http_protocol_options.idle_timeout Connection-wide idle.
stream_idle_timeout HttpConnectionManager.stream_idle_timeout Per-stream idle.
drain_timeout HttpConnectionManager.drain_timeout After GOAWAY / drain, how long to wait before forcefully closing.

The router applies its own route.timeout in addition.

Observability hooks

The HCM is the entry point for several cross-cutting concerns:

  • Access logs. Configured AccessLog instances (source/extensions/access_loggers/) are invoked when the stream completes (and optionally periodically). The formatter system in source/common/formatter/ backs the access-log substitution language.
  • Tracing. Tracing::HttpTracerImpl (source/common/tracing/http_tracer_impl.cc) creates a span when the HCM enters decodeHeaders. Tracer extensions (source/extensions/tracers/) export it.
  • Stats. ConnectionManagerStats (counters like downstream_rq_total, downstream_rq_2xx, …) live on every HCM instance.
  • Stream info. Each request's StreamInfo is the canonical record — used by access log formatters, filters, retry policies, and tracing.

Drain and GOAWAY

When the drain manager signals drain:

  • HTTP/1 listeners add Connection: close to in-flight responses.
  • HTTP/2 sends a GOAWAY immediately, then a second one with the highest stream ID after drain_timeout.
  • HTTP/3 sends a GOAWAY frame.

The HCM listens for the drain decision via a Network::DrainDecision reference passed at construction.

Overload integration

Server::OverloadManager (overload manager) can register overload actions with the HCM:

  • envoy.overload_actions.stop_accepting_requests — return 503.
  • envoy.overload_actions.disable_http_keepalive — close after each response.
  • envoy.overload_actions.reset_streams_using_excessive_memory — reset streams that buffer too much.

These reduce CPU/memory pressure without crashing.

Integration points

Entry points for modification

  • Adding a new HTTP filter: create a directory under source/extensions/filters/http/<name>/, register a factory, add to extensions_build_config.bzl. Read patterns and conventions and an existing simple filter (e.g. header_mutation) for the boilerplate.
  • Modifying request lifecycle: read conn_manager_impl.ccActiveStream::decodeHeaders, encodeHeaders, and the timer setup are the central paths.
  • Modifying filter chain semantics: read filter_manager.cc.
  • Adding a header behaviour: most goes through ConnectionManagerUtility (conn_manager_utility.cc).

See also

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

HTTP connection manager – Envoy wiki | Factory