Adding a Protocol
On this page
Overview
Protocols translate between external network protocols and the internal filter pipeline. Each protocol registers one or more services on the network backend’s runtime that bind listeners and dispatch traffic through the filter pipeline. (A protocol is what a listener speaks; a backend is the library that owns the sockets. To add a backend instead, see Adding a Network Backend.)
Steps
1. Implement Protocol
Create a module under crates/protocol/src/ and implement
the Protocol trait:
pub trait Protocol: Send {
fn register(
self: Box<Self>,
server: &mut praxis_core::backend::Runtime,
config: &Config,
pipelines: &ListenerPipelines,
) -> Result<Vec<watch::Sender<bool>>, ProxyError>;
}
register filters listeners by protocol kind, resolves
pipelines from ListenerPipelines, and registers
services on the backend runtime (backend::Runtime is
the selected backend’s runtime type). Return any TLS
certificate watcher shutdown senders; the caller keeps
them alive until server shutdown.
Reference implementations (exposed as
praxis_protocol::backend::{Http, Tcp}):
- HTTP:
crates/protocol/src/http/pingora/mod.rs(PingoraHttp) - TCP:
crates/protocol/src/tcp/service.rs(PingoraTcp)
2. Add ProtocolKind variant
Add a variant to ProtocolKind in
crates/core/src/config/listener.rs:
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ProtocolKind {
#[default]
Http,
Tcp,
// NewProtocol,
}
The #[serde(rename_all = "lowercase")] attribute maps
YAML values (e.g. protocol: tcp) to enum variants.
3. Wire in server.rs
In crates/server/src/server.rs, add a branch to
register_protocols that checks for listeners using
the new protocol kind and registers the implementation:
if config.listeners.iter().any(|l| l.protocol == ProtocolKind::NewProtocol) {
let shutdowns = Box::new(NewProtocolImpl)
.register(server, config, pipelines)
.unwrap_or_else(|e| fatal(&e));
all_shutdowns.extend(shutdowns);
}
4. Add filter compatibility
If the protocol uses a different filter trait than
HttpFilter or TcpFilter, define the new trait in
crates/filter/src/ and ensure the pipeline engine can
dispatch to it.
5. Test and document
- Add unit tests for the protocol implementation
- Add integration tests under
tests/integration/ - Add example configs under
examples/configs/ - Update
examples/README.md - Update
docs/features.mdwith the new protocol