Skip to main content

modo/middleware/
mod.rs

1//! # modo::middleware
2//!
3//! Universal HTTP middleware for the modo web framework.
4//!
5//! Provides a collection of Tower-compatible middleware layers covering
6//! the most common cross-cutting concerns — compression, request IDs,
7//! panic recovery, CORS, CSRF, centralised error rendering, security
8//! headers, request tracing, and rate limiting. Always available (no
9//! feature flag required).
10//!
11//! ## Relationship to `modo::middlewares`
12//!
13//! This module ships the framework-universal layers. The virtual
14//! [`modo::middlewares`](crate::middlewares) module is a flat
15//! wiring-site index that re-exports **both** these universal
16//! middlewares **and** domain-specific layers from feature-gated
17//! modules (e.g. `tenant`, `auth`, `flash`, `ip`, `tier`,
18//! `geolocation`, `template`). Reach for `modo::middlewares` when you
19//! want a single namespace at your `.layer(...)` call sites; reach for
20//! `modo::middleware` when you only need the universal layers or the
21//! supporting configuration and extractor types.
22//!
23//! ## Provided items
24//!
25//! | Function / type | Purpose |
26//! |---|---|
27//! | [`compression`] | Compress responses (gzip, deflate, brotli, zstd) |
28//! | [`request_id`] | Set / propagate `x-request-id` header |
29//! | [`catch_panic`] | Convert handler panics into 500 responses |
30//! | [`cors`] / [`cors_with`] | CORS headers (static or dynamic origins) |
31//! | [`CorsConfig`] | CORS configuration |
32//! | [`subdomains`] / [`urls`] | CORS origin predicates |
33//! | [`csrf`] / [`CsrfConfig`] | Double-submit signed-cookie CSRF protection |
34//! | [`CsrfToken`] | CSRF token in request/response extensions |
35//! | [`error_handler`] | Centralised error-response rendering |
36//! | [`security_headers`] / [`SecurityHeadersConfig`] | Security response headers |
37//! | [`tracing`] | HTTP request/response lifecycle spans |
38//! | [`rate_limit`] / [`rate_limit_with`] | Token-bucket rate limiting |
39//! | [`RateLimitConfig`] | Rate-limit configuration |
40//! | [`RateLimitLayer`] | Tower layer produced by `rate_limit` / `rate_limit_with` |
41//! | [`KeyExtractor`] | Trait for custom rate-limit key extraction |
42//! | [`PeerIpKeyExtractor`] / [`GlobalKeyExtractor`] | Built-in key extractors |
43//!
44//! ## Quick start
45//!
46//! ```rust,no_run
47//! use axum::{Router, routing::get};
48//! use axum::response::IntoResponse;
49//! use modo::middleware::*;
50//!
51//! async fn render_error(err: modo::Error, _parts: http::request::Parts) -> axum::response::Response {
52//!     (err.status(), err.message().to_string()).into_response()
53//! }
54//!
55//! let app: Router = Router::new()
56//!     .route("/", get(|| async { "hello" }))
57//!     .layer(error_handler(render_error))
58//!     .layer(compression())
59//!     .layer(request_id())
60//!     .layer(catch_panic())
61//!     .layer(tracing());
62//! ```
63
64mod catch_panic;
65mod compression;
66mod cors;
67mod csrf;
68mod error_handler;
69mod rate_limit;
70mod request_id;
71mod security_headers;
72mod tracing;
73
74pub use self::tracing::tracing;
75pub use catch_panic::catch_panic;
76pub use compression::compression;
77pub use cors::{CorsConfig, cors, cors_with, subdomains, urls};
78pub use csrf::{CsrfConfig, CsrfToken, csrf};
79pub use error_handler::error_handler;
80pub use rate_limit::{
81    GlobalKeyExtractor, KeyExtractor, PeerIpKeyExtractor, RateLimitConfig, RateLimitLayer,
82    rate_limit, rate_limit_with,
83};
84pub use request_id::request_id;
85pub use security_headers::{SecurityHeadersConfig, security_headers};