pub struct HttpFilterContext<'a> {Show 36 fields
pub buffered_request_body: Option<Bytes>,
pub body_done_indices: Vec<bool>,
pub branch_iterations: HashMap<Arc<str>, u32>,
pub client_addr: Option<IpAddr>,
pub cluster: Option<Arc<str>>,
pub current_filter_id: Option<usize>,
pub downstream_tls: bool,
pub metrics_route: Option<SharedString>,
pub peer_identity: Option<TlsPeerIdentity>,
pub extensions: RequestExtensions,
pub executed_filter_indices: Vec<bool>,
pub extra_request_headers: Vec<(Cow<'static, str>, String)>,
pub request_headers_to_remove: Vec<HeaderName>,
pub request_headers_to_set: Vec<(HeaderName, HeaderValue)>,
pub filter_metadata: HashMap<String, String>,
pub pre_read_mutations: Vec<TrustedHeaderMutation>,
pub structured_metadata: HashMap<String, Value>,
pub filter_results: HashMap<&'static str, FilterResultSet>,
pub filter_state: HashMap<usize, Box<dyn Any + Send + Sync>>,
pub health_registry: Option<&'a HealthRegistry>,
pub id_generator: &'a IdGenerator,
pub kv_stores: Option<&'a KvStoreRegistry>,
pub subrequest_client: Option<&'a SubRequestClient>,
pub subrequest_response_mode: SubRequestResponseMode,
pub request: &'a Request,
pub request_body_bytes: u64,
pub request_body_mode: BodyMode,
pub request_start: Instant,
pub response_body_bytes: u64,
pub response_body_mode: BodyMode,
pub response_header: Option<&'a mut Response>,
pub response_headers_modified: bool,
pub selected_endpoint_index: Option<usize>,
pub time_source: &'a dyn TimeSource,
pub rewritten_path: Option<String>,
pub upstream: Option<Upstream>,
}Expand description
Per-request mutable state shared across all HTTP filters.
Created by the protocol layer for each incoming request. Filters read and mutate it to select clusters, choose upstreams, and inject headers.
Fields§
§buffered_request_body: Option<Bytes>Complete request body captured by protocol pre-read, when the
pipeline’s effective request mode is BodyMode::StreamBuffer.
This remains available during on_request even when a filter’s body
hook was skipped because body-derived header mutations changed its
request conditions between the pre-read and header phases.
body_done_indices: Vec<bool>Per-filter body-done tracking. When true at index i,
filter i is skipped for remaining body chunks.
branch_iterations: HashMap<Arc<str>, u32>Iteration counters for re-entrant branches. Branch name -> current iteration count.
client_addr: Option<IpAddr>Downstream client IP address (from the TCP connection).
cluster: Option<Arc<str>>The cluster name selected by the router filter.
current_filter_id: Option<usize>Stable invocation ID of the filter currently executing.
Assigned at pipeline build time and unique within the
request’s pinned FilterPipeline. Set by the pipeline
executor before each filter hook call and cleared after.
Filter state accessors use this as the storage key so
that multiple instances of the same filter type — including
filters in branch chains — get independent state.
downstream_tls: boolWhether the downstream connection uses TLS.
Set by the protocol layer from the connection’s SSL
digest. Used by the forwarded headers filter to derive
X-Forwarded-Proto from the actual connection state
rather than the request URI scheme (which is absent
in HTTP/1.1).
metrics_route: Option<SharedString>Matched route path pattern for metrics (bounded; not the raw URL).
peer_identity: Option<TlsPeerIdentity>Verified downstream TLS peer identity, if the connection is mTLS and the peer presented a valid client certificate.
None for plain-TLS or non-TLS connections, or when the
client did not send a certificate (e.g. client_cert_mode: request with no cert). Populated once from the SSL digest
before the first filter runs and preserved across all
subsequent build_filter_context() calls for the request.
extensions: RequestExtensionsType-safe request-scoped extension container.
Filters store and retrieve arbitrary typed values that
persist across all Pingora lifecycle phases (request,
request body, response, response body, logging). Keyed
by TypeId, so only one value per concrete type. Use
private newtypes to avoid collisions between independent
filters.
executed_filter_indices: Vec<bool>Tracks which pipeline filter indices actually executed
during the request phase. The response phase skips
filters that did not run (e.g. due to SkipTo).
extra_request_headers: Vec<(Cow<'static, str>, String)>Extra headers to inject into the upstream request.
request_headers_to_remove: Vec<HeaderName>Headers to remove from the upstream request.
request_headers_to_set: Vec<(HeaderName, HeaderValue)>Headers to set (overwrite) on the upstream request.
filter_metadata: HashMap<String, String>Durable per-request metadata that persists across all
Pingora lifecycle phases (request, request-body, response,
response-body, logging). Unlike filter_results which
are cleared after branch evaluation, metadata survives
for the entire request lifetime.
Keys use dot-prefix namespacing by convention
(e.g. json_rpc.kind, classifier.label).
pre_read_mutations: Vec<TrustedHeaderMutation>Ordered log of trusted header mutations from pre-read body processing. Replayed by the protocol layer after the request-phase pipeline runs.
structured_metadata: HashMap<String, Value>Structured per-request metadata keyed by namespace.
Unlike filter_metadata which stores flat string
key-value pairs, this stores nested JSON values per
namespace. Used by filters that need to pass structured
data (e.g. dynamic metadata from external filters) across lifecycle
phases.
filter_results: HashMap<&'static str, FilterResultSet>Filter result map: filter_name -> result entries.
Filters write string key-value pairs here during
on_request or on_response. The pipeline executor
reads these to evaluate branch conditions. Cleared
after branch evaluation at each filter.
filter_state: HashMap<usize, Box<dyn Any + Send + Sync>>Typed per-filter state that persists across all lifecycle phases (request, request-body, response, response-body).
Keyed by stable filter invocation ID, unique within the
request’s pinned FilterPipeline. Swapped into each
HttpFilterContext from the protocol-layer request context
and written back after filter execution, following the same
pattern as filter_metadata.
health_registry: Option<&'a HealthRegistry>Shared health registry for endpoint health lookups.
id_generator: &'a IdGeneratorShared request ID generator.
kv_stores: Option<&'a KvStoreRegistry>Named key-value stores for runtime mappings.
subrequest_client: Option<&'a SubRequestClient>Shared sub-request client for iterative sub-requests.
subrequest_response_mode: SubRequestResponseModeFilter-selected transport mode for the next sub-request response.
Every newly constructed context starts in Buffered mode. A caller
that reuses context state across iterative steps must reset this field
before running the next step pipeline.
request: &'a RequestTransport-agnostic request headers, URI, and method.
request_body_bytes: u64Accumulated request body bytes seen so far.
request_body_mode: BodyModePer-request body delivery mode for the request direction.
Defaults to BodyMode::Stream; filters may upgrade it
via set_request_body_mode.
request_start: InstantWhen the request was received; available in all phases.
response_body_bytes: u64Accumulated response body bytes seen so far.
response_body_mode: BodyModePer-request body delivery mode for the response direction.
Defaults to BodyMode::Stream; filters may upgrade it
via set_response_body_mode.
response_header: Option<&'a mut Response>The upstream response headers, available during on_response.
None during the request phase.
response_headers_modified: boolOptional hint that a filter modified the response headers during
on_response, used by the protocol layer to skip unnecessary work.
Setting this is never required for correctness: the protocol layer independently compares the response header name sequence before and after the pipeline and rebuilds when it changed. Leaving it unset only forgoes an optimisation, never an edit.
selected_endpoint_index: Option<usize>Index of the selected endpoint in the cluster’s endpoint list. Set by the load balancer filter for use by passive health checking in the protocol layer.
time_source: &'a dyn TimeSourceWall-clock time source for timestamp generation.
rewritten_path: Option<String>Rewritten URI path for the upstream request.
Set by the path_rewrite or url_rewrite filter during
on_request. Applied to the upstream RequestHeader in the
protocol layer.
The router checks this field before the original request URI.
If a preceding filter sets rewritten_path, the router
matches against it, enabling “rewrite then route” pipelines.
If both path_rewrite and url_rewrite appear in the same
pipeline, only the last writer’s value takes effect.
Pipeline validation rejects this by default; set
allow_rewrite_override: true on the later filter to
permit it. Or, better yet, don’t.
upstream: Option<Upstream>The upstream peer selected by the load balancer filter.
Implementations§
Source§impl HttpFilterContext<'_>
impl HttpFilterContext<'_>
Sourcepub fn cluster_name(&self) -> Option<&str>
pub fn cluster_name(&self) -> Option<&str>
Selected cluster name, if any.
Sourcepub fn upstream_addr(&self) -> Option<&str>
pub fn upstream_addr(&self) -> Option<&str>
Upstream peer address, if selected.
Sourcepub fn subrequest_response_mode(&self) -> SubRequestResponseMode
pub fn subrequest_response_mode(&self) -> SubRequestResponseMode
Return the response transport mode selected for the next sub-request.
Sourcepub fn set_subrequest_response_mode(&mut self, mode: SubRequestResponseMode)
pub fn set_subrequest_response_mode(&mut self, mode: SubRequestResponseMode)
Select the response transport mode for the next sub-request.
Filters own this decision; the transport layer only executes it.
Sourcepub fn get_metadata(&self, key: &str) -> Option<&str>
pub fn get_metadata(&self, key: &str) -> Option<&str>
Read a durable metadata value by key.
Sourcepub fn request_id(&self) -> Option<&str>
pub fn request_id(&self) -> Option<&str>
X-Request-ID header value, if present and valid UTF-8.
Sourcepub fn set_metadata(&mut self, key: impl Into<String>, value: impl Into<String>)
pub fn set_metadata(&mut self, key: impl Into<String>, value: impl Into<String>)
Write a durable metadata value that persists across all phases.
Keys should use dot-prefix namespacing
(e.g. json_rpc.kind, classifier.label). Keys are limited to
64 bytes and values to 256 bytes to bound per-request
memory growth.
Sourcepub fn set_request_body_mode(&mut self, mode: BodyMode)
pub fn set_request_body_mode(&mut self, mode: BodyMode)
Upgrade the request body delivery mode for this request.
Merges mode into the current mode using ratchet-up
semantics: StreamBuffer > SizeLimit > Stream. A mode
can only be upgraded, never downgraded.
Sourcepub fn set_response_body_mode(&mut self, mode: BodyMode)
pub fn set_response_body_mode(&mut self, mode: BodyMode)
Upgrade the response body delivery mode for this request.
Same ratchet-up semantics as set_request_body_mode.
Sourcepub fn insert_filter_state<T: Any + Send + Sync>(&mut self, state: T)
pub fn insert_filter_state<T: Any + Send + Sync>(&mut self, state: T)
Store typed per-request state for the currently executing filter.
Uses current_filter_id as the storage key, so multiple
instances of the same filter type get independent state.
No-op if called outside of pipeline execution (when
current_filter_id is None).
Sourcepub fn get_filter_state<T: Any + Send + Sync>(&self) -> Option<&T>
pub fn get_filter_state<T: Any + Send + Sync>(&self) -> Option<&T>
Retrieve a shared reference to the typed state stored by the currently executing filter.
Returns None when no state is stored, when the stored type
does not match T, or when called outside pipeline execution.
Sourcepub fn get_filter_state_mut<T: Any + Send + Sync>(&mut self) -> Option<&mut T>
pub fn get_filter_state_mut<T: Any + Send + Sync>(&mut self) -> Option<&mut T>
Retrieve a mutable reference to the typed state stored by the currently executing filter.
Returns None under the same conditions as
get_filter_state.
Sourcepub fn remove_filter_state<T: Any + Send + Sync>(&mut self) -> Option<T>
pub fn remove_filter_state<T: Any + Send + Sync>(&mut self) -> Option<T>
Remove and return the typed state stored by the currently executing filter.
Returns None when no state is stored, when the stored type
does not match T, or when called outside pipeline execution.
A type mismatch does not destroy the stored entry.
Sourcepub fn resolve_trusted_header(
&self,
name: &HeaderName,
) -> Result<Option<String>, String>
pub fn resolve_trusted_header( &self, name: &HeaderName, ) -> Result<Option<String>, String>
Resolve the effective value of a trusted header from the pre-read mutation log.
Walks the ordered mutation log forward, applying each mutation in sequence. Only trusted sources (pre-read filter mutations) are considered; the original request headers are intentionally excluded.
§Errors
Returns an error if:
- A
Setmutation contains a non-textHeaderValue - Multiple distinct values remain after all mutations (ambiguous final state)
Sourcepub fn pending_header_value(
&self,
name: &HeaderName,
) -> Result<PendingHeaderResult, String>
pub fn pending_header_value( &self, name: &HeaderName, ) -> Result<PendingHeaderResult, String>
Resolve the effective pending value of a header from the mutation lists (not the original request).
Returns a tri-state PendingHeaderResult so callers can
distinguish “not mentioned” from “explicitly removed.”
Applies mutations in HTTP order: remove → set → add.
Multiple distinct values are rejected as ambiguous. This is
intentionally stricter than the normal pipeline’s last-write-wins
semantics because routing-critical headers (used by
endpoint_selector) must have a single unambiguous value.
§Errors
Returns an error if a pending Set value contains
non-text bytes, or if the final state has multiple
distinct values.
Sourcepub fn set_structured_metadata(
&mut self,
namespace: &str,
key: &str,
value: Value,
)
pub fn set_structured_metadata( &mut self, namespace: &str, key: &str, value: Value, )
Set a structured metadata value under a namespace.
Each namespace is stored as a JSON object; key becomes
a field within that object. If the namespace does not yet
exist, a new empty object is created first.
A per-namespace key limit of 64 prevents unbounded accumulation from streaming processors. New keys are silently dropped once the limit is reached; existing keys can still be overwritten.
Sourcepub fn get_structured_metadata(
&self,
namespace: &str,
key: &str,
) -> Option<&Value>
pub fn get_structured_metadata( &self, namespace: &str, key: &str, ) -> Option<&Value>
Get a structured metadata value from a namespace.
Returns None when the namespace is absent, when it is
not a JSON object, or when key is not present within it.
Sourcepub fn merge_structured_metadata(
&mut self,
namespace: &str,
values: Map<String, Value>,
)
pub fn merge_structured_metadata( &mut self, namespace: &str, values: Map<String, Value>, )
Merge a complete namespace object, overwriting existing keys.
Keys already present in the namespace are overwritten;
keys absent from values are left untouched. New keys
that would exceed the per-namespace limit of 64
are silently dropped.