Skip to main content

FilterPipeline

Struct FilterPipeline 

Source
pub struct FilterPipeline { /* private fields */ }
Expand description

An ordered list of filters executed on every request.

use praxis_filter::{FilterPipeline, FilterRegistry};

let registry = FilterRegistry::with_builtins();
let pipeline = FilterPipeline::build(&mut [], &registry).unwrap();
assert!(pipeline.is_empty());

Implementations§

Source§

impl FilterPipeline

Source

pub fn build( entries: &mut [FilterEntry], registry: &FilterRegistry, ) -> Result<Self, FilterError>

Build a pipeline by instantiating each filter entry via the registry.

Conditions are moved out of entries via mem::take to avoid cloning. After this call, each entry’s condition vecs are empty.

§Errors

Returns FilterError if any filter fails to instantiate.

Source

pub fn build_with_chains( entries: &mut [FilterEntry], registry: &FilterRegistry, chains: &HashMap<&str, &[FilterEntry]>, ) -> Result<Self, FilterError>

Build a pipeline with branch chain resolution.

Like build, but also resolves branch_chains on each filter entry into runtime ResolvedBranch types using the provided chain lookup table.

§Errors

Returns FilterError if any filter fails to instantiate or any branch chain reference is unresolvable.

Source

pub fn ordering_errors( &self, entries: &[FilterEntry], allow_open_security: bool, ) -> Vec<String>

Validate the pipeline for structural misconfigurations that would cause runtime failures (502s, unreachable filters, cluster mismatches).

use praxis_filter::{FailureMode, FilterEntry, FilterPipeline, FilterRegistry};

let registry = FilterRegistry::with_builtins();
let mut entries = vec![FilterEntry {
    branch_chains: None,
    filter_type: "load_balancer".into(),
    config: serde_yaml::from_str("clusters: []").unwrap(),
    conditions: vec![],
    name: None,
    response_conditions: vec![],
    failure_mode: FailureMode::default(),
}];
let pipeline = FilterPipeline::build(&mut entries, &registry).unwrap();
let errors = pipeline.ordering_errors(&entries, false);
assert!(
    errors
        .iter()
        .any(|e| e.contains("without a preceding router"))
);
Source

pub fn ordering_warnings(&self) -> Vec<String>

Check for non-fatal ordering advisories.

Currently detects: all routers conditional with no fallback.

use praxis_filter::{FailureMode, FilterEntry, FilterPipeline, FilterRegistry};

let registry = FilterRegistry::with_builtins();
let mut entries = vec![FilterEntry {
    branch_chains: None,
    filter_type: "router".into(),
    config: serde_yaml::from_str("routes: []").unwrap(),
    conditions: vec![praxis_core::config::Condition::When(
        praxis_core::config::ConditionMatch {
            path: None,
            path_prefix: Some("/api".to_owned()),
            methods: None,
            headers: None,
        },
    )],
    name: None,
    response_conditions: vec![],
    failure_mode: FailureMode::default(),
}];
let pipeline = FilterPipeline::build(&mut entries, &registry).unwrap();
let warnings = pipeline.ordering_warnings();
assert!(
    warnings
        .iter()
        .any(|w| w.contains("all router filters are conditional"))
);
Source§

impl FilterPipeline

Source

pub async fn execute_http_request( &self, ctx: &mut HttpFilterContext<'_>, ) -> Result<FilterAction, FilterError>

Run all HTTP request filters in order.

Tracks which filter indices actually executed so the response phase can skip filters that were bypassed (e.g. by SkipTo).

§Errors

Returns FilterError if any filter fails.

Source

pub async fn execute_http_response( &self, ctx: &mut HttpFilterContext<'_>, ) -> Result<FilterAction, FilterError>

Run all HTTP response filters in reverse order.

Skips filters that did not execute during the request phase (tracked by executed_filter_indices).

§Errors

Returns FilterError if any filter fails.

Source

pub async fn execute_http_request_body( &self, ctx: &mut HttpFilterContext<'_>, body: &mut Option<Bytes>, end_of_stream: bool, ) -> Result<FilterAction, FilterError>

Run all HTTP request body filters in order.

Filters that previously returned BodyDone are skipped.

§Errors

Returns FilterError if any body filter fails.

Source

pub fn execute_http_response_body( &self, ctx: &mut HttpFilterContext<'_>, body: &mut Option<Bytes>, end_of_stream: bool, ) -> Result<FilterAction, FilterError>

Run all HTTP response body filters in reverse order.

Filters that previously returned BodyDone are skipped.

§Errors

Returns FilterError if any body filter fails.

Source§

impl FilterPipeline

Source

pub async fn execute_tcp_connect( &self, ctx: &mut TcpFilterContext<'_>, ) -> Result<FilterAction, FilterError>

Run all TCP connect filters in order.

TCP filters do not participate in branch chain evaluation currently. TCP pipelines execute filters sequentially without conditional branching or rejoin logic.

§Errors

Returns FilterError if any filter rejects or fails.

Source

pub async fn execute_tcp_disconnect( &self, ctx: &mut TcpFilterContext<'_>, ) -> Result<(), FilterError>

Run all TCP disconnect filters in reverse order.

§Errors

Returns FilterError if any filter fails.

Source§

impl FilterPipeline

Source

pub fn apply_body_limits( &mut self, max_request: Option<usize>, max_response: Option<usize>, allow_unbounded: bool, ) -> Result<(), FilterError>

Apply global body size ceilings.

When no filter requires body access (mode is Stream), uses SizeLimit to enforce the ceiling without buffering. When a filter already requested StreamBuffer, the ceiling tightens the existing limit.

§Errors

Returns FilterError if a StreamBuffer has no byte limit and allow_unbounded is false.

Source

pub fn body_capabilities(&self) -> &BodyCapabilities

Pre-computed body processing capabilities for this pipeline.

Source

pub fn needs_body_filters(&self) -> bool

Whether any filter in the pipeline needs body access.

Source

pub fn len(&self) -> usize

Number of filters in the pipeline.

Source

pub fn is_empty(&self) -> bool

Whether the pipeline has no filters.

Source

pub fn compression_config(&self) -> Option<&CompressionConfig>

Compression configuration, if a compression filter is present.

Source

pub fn set_health_registry(&mut self, registry: HealthRegistry)

Set the shared HealthRegistry for this pipeline.

Source

pub fn health_registry(&self) -> Option<&HealthRegistry>

The shared health registry, if set.

Source

pub fn id_generator(&self) -> &IdGenerator

The shared request ID generator.

Source

pub fn set_id_generator(&mut self, generator: Arc<IdGenerator>)

Override the IdGenerator for this pipeline.

Source

pub fn kv_stores(&self) -> Option<&KvStoreRegistry>

The shared KV store registry, if set.

Source

pub fn set_kv_stores(&mut self, stores: KvStoreRegistry)

Set the shared KvStoreRegistry for this pipeline.

Source

pub fn add_pipeline_extension(&mut self, ext: Box<dyn PipelineExtension>)

Register an external pipeline extension.

Extensions are called once per request via prepare_extensions to inject pipeline-scoped resources into the per-request RequestExtensions container.

Source

pub fn prepare_extensions(&self, extensions: &mut RequestExtensions)

Inject pipeline-level resources into per-request extensions.

Called by the protocol adapter when building each request’s filter context. Delegates to each registered PipelineExtension.

Source

pub fn time_source(&self) -> &dyn TimeSource

The wall-clock time source.

Source

pub fn set_time_source(&mut self, source: Arc<dyn TimeSource>)

Override the TimeSource for this pipeline.

Source

pub fn apply_insecure_options(&self, options: &InsecureOptions)

Apply InsecureOptions to all filters in the pipeline.

Delegates to each filter’s apply_insecure_options method. Filters that support insecure overrides (e.g. CSRF log-only mode) handle the relevant flags; others ignore the call.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more