Skip to main content

ferrum_server/
middleware.rs

1//! Middleware configuration types
2//!
3//! This module defines configuration types for various middleware components.
4
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::time::Duration;
8
9/// Middleware configuration
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct MiddlewareConfig {
12    /// Authentication middleware
13    pub auth: Option<AuthConfig>,
14
15    /// CORS middleware
16    pub cors: Option<CorsConfig>,
17
18    /// Logging middleware
19    pub logging: Option<LoggingConfig>,
20
21    /// Compression middleware
22    pub compression: Option<CompressionConfig>,
23
24    /// Rate limiting middleware
25    pub rate_limit: Option<RateLimitConfig>,
26
27    /// Timeout middleware
28    pub timeout: Option<TimeoutConfig>,
29
30    /// Custom middleware configurations
31    pub custom: HashMap<String, serde_json::Value>,
32}
33
34/// Authentication configuration
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct AuthConfig {
37    /// Enable authentication
38    pub enabled: bool,
39
40    /// JWT secret key
41    pub jwt_secret: Option<String>,
42
43    /// JWT issuer
44    pub jwt_issuer: Option<String>,
45
46    /// JWT audience
47    pub jwt_audience: Option<String>,
48
49    /// Token expiration time
50    pub token_expiration: Duration,
51
52    /// API key validation endpoint
53    pub api_key_endpoint: Option<String>,
54
55    /// Default permissions
56    pub default_permissions: Vec<String>,
57
58    /// Admin API keys
59    pub admin_keys: Vec<String>,
60}
61
62/// CORS configuration
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct CorsConfig {
65    /// Enable CORS
66    pub enabled: bool,
67
68    /// Allowed origins
69    pub allowed_origins: Vec<String>,
70
71    /// Allowed methods
72    pub allowed_methods: Vec<String>,
73
74    /// Allowed headers
75    pub allowed_headers: Vec<String>,
76
77    /// Exposed headers
78    pub exposed_headers: Vec<String>,
79
80    /// Allow credentials
81    pub allow_credentials: bool,
82
83    /// Max age for preflight requests
84    pub max_age: Duration,
85}
86
87/// Logging configuration
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct LoggingConfig {
90    /// Enable request logging
91    pub enabled: bool,
92
93    /// Log level
94    pub level: LogLevel,
95
96    /// Include request body
97    pub include_body: bool,
98
99    /// Include response body
100    pub include_response: bool,
101
102    /// Include headers
103    pub include_headers: bool,
104
105    /// Exclude paths from logging
106    pub exclude_paths: Vec<String>,
107
108    /// Log format
109    pub format: LogFormat,
110}
111
112/// Log levels
113#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
114pub enum LogLevel {
115    Trace,
116    Debug,
117    Info,
118    Warn,
119    Error,
120}
121
122/// Log formats
123#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
124pub enum LogFormat {
125    Json,
126    Text,
127    Combined,
128    Common,
129}
130
131/// Compression configuration
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct CompressionConfig {
134    /// Enable compression
135    pub enabled: bool,
136
137    /// Compression algorithms
138    pub algorithms: Vec<CompressionAlgorithm>,
139
140    /// Minimum response size to compress
141    pub min_size: usize,
142
143    /// Compression level (0-9)
144    pub level: u32,
145
146    /// Content types to compress
147    pub content_types: Vec<String>,
148}
149
150/// Compression algorithms
151#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
152pub enum CompressionAlgorithm {
153    Gzip,
154    Deflate,
155    Brotli,
156    Zstd,
157}
158
159/// Rate limiting configuration
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct RateLimitConfig {
162    /// Enable rate limiting
163    pub enabled: bool,
164
165    /// Default rate limits
166    pub default_limits: RateLimits,
167
168    /// Per-client rate limits
169    pub client_limits: HashMap<String, RateLimits>,
170
171    /// Rate limit storage backend
172    pub storage: RateLimitStorage,
173
174    /// Rate limit headers
175    pub include_headers: bool,
176}
177
178/// Rate limits specification
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct RateLimits {
181    /// Requests per minute
182    pub requests_per_minute: u32,
183
184    /// Requests per hour
185    pub requests_per_hour: u32,
186
187    /// Tokens per minute
188    pub tokens_per_minute: u32,
189
190    /// Tokens per hour
191    pub tokens_per_hour: u32,
192
193    /// Concurrent requests
194    pub concurrent_requests: u32,
195}
196
197/// Rate limit storage backends
198#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
199pub enum RateLimitStorage {
200    Memory,
201    Redis,
202    Database,
203}
204
205/// Timeout configuration
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct TimeoutConfig {
208    /// Enable timeout middleware
209    pub enabled: bool,
210
211    /// Request timeout
212    pub request_timeout: Duration,
213
214    /// Keep-alive timeout
215    pub keep_alive_timeout: Duration,
216
217    /// Read timeout
218    pub read_timeout: Duration,
219
220    /// Write timeout
221    pub write_timeout: Duration,
222}
223
224impl Default for AuthConfig {
225    fn default() -> Self {
226        Self {
227            enabled: false,
228            jwt_secret: None,
229            jwt_issuer: Some("ferrum-infer".to_string()),
230            jwt_audience: Some("ferrum-api".to_string()),
231            token_expiration: Duration::from_secs(3600),
232            api_key_endpoint: None,
233            default_permissions: vec![],
234            admin_keys: vec![],
235        }
236    }
237}
238
239impl Default for CorsConfig {
240    fn default() -> Self {
241        Self {
242            enabled: true,
243            allowed_origins: vec!["*".to_string()],
244            allowed_methods: vec!["GET".to_string(), "POST".to_string(), "OPTIONS".to_string()],
245            allowed_headers: vec![
246                "Content-Type".to_string(),
247                "Authorization".to_string(),
248                "X-Requested-With".to_string(),
249            ],
250            exposed_headers: vec![],
251            allow_credentials: false,
252            max_age: Duration::from_secs(86400),
253        }
254    }
255}
256
257impl Default for LoggingConfig {
258    fn default() -> Self {
259        Self {
260            enabled: true,
261            level: LogLevel::Info,
262            include_body: false,
263            include_response: false,
264            include_headers: false,
265            exclude_paths: vec!["/health".to_string(), "/metrics".to_string()],
266            format: LogFormat::Json,
267        }
268    }
269}
270
271impl Default for CompressionConfig {
272    fn default() -> Self {
273        Self {
274            enabled: true,
275            algorithms: vec![CompressionAlgorithm::Gzip, CompressionAlgorithm::Deflate],
276            min_size: 1024,
277            level: 6,
278            content_types: vec![
279                "application/json".to_string(),
280                "text/plain".to_string(),
281                "text/html".to_string(),
282            ],
283        }
284    }
285}
286
287impl Default for RateLimitConfig {
288    fn default() -> Self {
289        Self {
290            enabled: false,
291            default_limits: RateLimits::default(),
292            client_limits: HashMap::new(),
293            storage: RateLimitStorage::Memory,
294            include_headers: true,
295        }
296    }
297}
298
299impl Default for RateLimits {
300    fn default() -> Self {
301        Self {
302            requests_per_minute: 60,
303            requests_per_hour: 1000,
304            tokens_per_minute: 10000,
305            tokens_per_hour: 100000,
306            concurrent_requests: 10,
307        }
308    }
309}
310
311impl Default for TimeoutConfig {
312    fn default() -> Self {
313        Self {
314            enabled: true,
315            request_timeout: Duration::from_secs(30),
316            keep_alive_timeout: Duration::from_secs(60),
317            read_timeout: Duration::from_secs(10),
318            write_timeout: Duration::from_secs(10),
319        }
320    }
321}