dwara_core/plugins/
mod.rs

1//! Native plugin filters and the unified plugin dispatch chain (DW-119).
2//!
3//! This module provides the compile-in extension path for filters written
4//! in Rust and linked into the gateway binary at build time -- the
5//! convenience/performance counterpart to the proxy-wasm host (DW-055).
6//! A native filter and a WASM plugin attach identically from config's
7//! point of view: both are entries in the top-level `plugins` list,
8//! referenced by name from routes, and both declare the same phase
9//! contract. Only the implementation differs -- a native filter is a
10//! Rust type implementing [`NativeFilter`] and registered with
11//! [`NativeRegistry`], while a WASM plugin is a `.wasm` module loaded by
12//! the `wasm` host.
13//!
14//! ## Phase contract (section 9.3)
15//!
16//! The phases and their outcome semantics mirror the proxy-wasm host
17//! exactly (see `wasm::runner::PhaseOutcome`). The four HTTP filter
18//! phases are:
19//!
20//! 1. `request_headers` -- after route resolution, before authn.
21//! 2. `request_body` -- after authn/authz/rate-limit, before upstream.
22//! 3. `response_headers` -- after the upstream responds, before masking.
23//! 4. `response_body` -- after masking, before compression.
24//!
25//! A native filter can short-circuit with a [`LocalResponse`] at any
26//! phase, exactly as a WASM plugin can via `proxy_send_http_response`.
27//!
28//! ## Unified dispatch
29//!
30//! [`PluginChain`] is the single integration seam the dataplane calls.
31//! Given a route's plugin names, the loaded WASM runner, and the native
32//! registry, it builds the per-request
33//! execution list combining native filters and WASM instances IN PHASE
34//! ORDER (deterministic, using the same ordering logic as
35//! `wasm::lifecycle::PluginLifecycle::phase_order`). It exposes the same
36//! phase methods and dispatches to each plugin in order, threading
37//! headers/body through and short-circuiting on `LocalResponse`/`Error`.
38//!
39//! ## Dependency direction
40//!
41//! `plugins` depends on `config` only. It does NOT depend on `wasm`:
42//! the unified chain is generic over a [`WasmDispatch`] adapter so the
43//! `wasm` domain (which depends on `plugins`) can bridge its per-request
44//! instances into the chain without an upward import. This keeps the
45//! dependency direction strictly downward.
46//!
47//! ## Dispatch wiring (DW-157)
48//!
49//! Both filter paths compile unconditionally in the OSS build (there
50//! are no cargo features for plugins): the dataplane builds one
51//! [`PluginChain`] per request on routes that reference plugins
52//! (`dataplane::plugin_dispatch`) and drives it at the four phase
53//! points above, always through the `wasm` domain's `WasmChainAdapter`
54//! (native-only chains carry an EMPTY instance set, so every per-name
55//! WASM dispatch passes through). [`NoWasm`] remains the no-op adapter
56//! for tests.
57
58pub mod chain;
59pub mod filter;
60pub mod registry;
61
62pub use chain::{ChainOutcome, NativeCreateFailure, NoWasm, PluginChain, WasmDispatch};
63pub use filter::{FilterOutcome, LocalResponse, NativeFilter};
64pub use registry::{NativeFilterFactory, NativeRegistry, RegistryError};