ferrotunnel_plugin/lib.rs
1//! # FerroTunnel Plugin System
2//!
3//! This crate provides an extensible plugin system for FerroTunnel, allowing you to
4//! inspect, modify, or reject HTTP requests and responses as they flow through the tunnel.
5//!
6//! ## Features
7//!
8//! - **Async-First** - All plugin hooks are async for non-blocking I/O
9//! - **Type-Safe** - Trait-based design with compile-time guarantees
10//! - **Lifecycle Management** - Plugin initialization and graceful shutdown
11//! - **Built-in Plugins** - Logger, token auth, and rate limiting included
12//!
13//! ## Quick Start
14//!
15//! ### Creating a Custom Plugin
16//!
17//! ```rust
18//! use ferrotunnel_plugin::{Plugin, PluginAction, RequestContext};
19//! use async_trait::async_trait;
20//!
21//! struct MyPlugin;
22//!
23//! #[async_trait]
24//! impl Plugin for MyPlugin {
25//! fn name(&self) -> &str {
26//! "my-plugin"
27//! }
28//!
29//! async fn on_request(
30//! &self,
31//! req: &mut http::Request<()>,
32//! ctx: &RequestContext,
33//! ) -> Result<PluginAction, Box<dyn std::error::Error + Send + Sync + 'static>> {
34//! // Inspect or modify the request
35//! if req.uri().path() == "/admin" {
36//! return Ok(PluginAction::Reject {
37//! status: 403,
38//! reason: "Access denied".to_string(),
39//! });
40//! }
41//! Ok(PluginAction::Continue)
42//! }
43//! }
44//! ```
45//!
46//! ### Registering Plugins
47//!
48//! ```rust,no_run
49//! use ferrotunnel_plugin::PluginRegistry;
50//! use std::sync::Arc;
51//! use tokio::sync::RwLock;
52//!
53//! # struct MyPlugin;
54//! # #[async_trait::async_trait]
55//! # impl ferrotunnel_plugin::Plugin for MyPlugin {
56//! # fn name(&self) -> &str { "my-plugin" }
57//! # }
58//! #
59//! #[tokio::main]
60//! async fn main() {
61//! let mut registry = PluginRegistry::new();
62//!
63//! // Register your custom plugin
64//! registry.register(Arc::new(RwLock::new(MyPlugin)));
65//!
66//! // Initialize all plugins
67//! let _ = registry.init_all().await;
68//! }
69//! ```
70//!
71//! ## Built-in Plugins
72//!
73//! ### Logger Plugin
74//!
75//! Logs all HTTP requests and responses:
76//!
77//! ```rust
78//! use ferrotunnel_plugin::builtin::LoggerPlugin;
79//! # use ferrotunnel_plugin::PluginRegistry;
80//! # use std::sync::Arc;
81//! # use tokio::sync::RwLock;
82//!
83//! let logger = LoggerPlugin::new().with_body_logging();
84//! # let mut registry = PluginRegistry::new();
85//! registry.register(Arc::new(RwLock::new(logger)));
86//! ```
87//!
88//! ### Token Auth Plugin
89//!
90//! Validates authentication tokens:
91//!
92//! ```rust
93//! use ferrotunnel_plugin::builtin::TokenAuthPlugin;
94//! # use ferrotunnel_plugin::PluginRegistry;
95//! # use std::sync::Arc;
96//! # use tokio::sync::RwLock;
97//!
98//! let auth = TokenAuthPlugin::new(vec!["secret-token".to_string()]);
99//! # let mut registry = PluginRegistry::new();
100//! registry.register(Arc::new(RwLock::new(auth)));
101//! ```
102//!
103//! ### Rate Limit Plugin
104//!
105//! Limits requests per tunnel:
106//!
107//! ```rust
108//! use ferrotunnel_plugin::builtin::RateLimitPlugin;
109//! # use ferrotunnel_plugin::PluginRegistry;
110//! # use std::sync::Arc;
111//! # use tokio::sync::RwLock;
112//! # use std::num::NonZero;
113//!
114//! let rate_limiter = RateLimitPlugin::new(NonZero::new(100).unwrap()); // 100 requests/second
115//! # let mut registry = PluginRegistry::new();
116//! registry.register(Arc::new(RwLock::new(rate_limiter)));
117//! ```
118//!
119//! ## Plugin Actions
120//!
121//! Plugins can return different actions:
122//!
123//! - `PluginAction::Continue` - Allow request, continue to next plugin
124//! - `PluginAction::Reject { status, reason }` - Reject with HTTP status
125//! - `PluginAction::Respond { status, headers, body }` - Send custom response
126//!
127//! ## See Also
128//!
129//! - [`Plugin`] - Core plugin trait
130//! - [`PluginRegistry`] - Plugin management and execution
131//! - [`PluginAction`] - Actions that plugins can return
132
133pub mod builtin;
134pub mod registry;
135pub mod traits;
136
137pub use registry::*;
138pub use traits::*;