1use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use std::time::Duration;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct MiddlewareConfig {
12 pub auth: Option<AuthConfig>,
14
15 pub cors: Option<CorsConfig>,
17
18 pub logging: Option<LoggingConfig>,
20
21 pub compression: Option<CompressionConfig>,
23
24 pub rate_limit: Option<RateLimitConfig>,
26
27 pub timeout: Option<TimeoutConfig>,
29
30 pub custom: HashMap<String, serde_json::Value>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct AuthConfig {
37 pub enabled: bool,
39
40 pub jwt_secret: Option<String>,
42
43 pub jwt_issuer: Option<String>,
45
46 pub jwt_audience: Option<String>,
48
49 pub token_expiration: Duration,
51
52 pub api_key_endpoint: Option<String>,
54
55 pub default_permissions: Vec<String>,
57
58 pub admin_keys: Vec<String>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct CorsConfig {
65 pub enabled: bool,
67
68 pub allowed_origins: Vec<String>,
70
71 pub allowed_methods: Vec<String>,
73
74 pub allowed_headers: Vec<String>,
76
77 pub exposed_headers: Vec<String>,
79
80 pub allow_credentials: bool,
82
83 pub max_age: Duration,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct LoggingConfig {
90 pub enabled: bool,
92
93 pub level: LogLevel,
95
96 pub include_body: bool,
98
99 pub include_response: bool,
101
102 pub include_headers: bool,
104
105 pub exclude_paths: Vec<String>,
107
108 pub format: LogFormat,
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
114pub enum LogLevel {
115 Trace,
116 Debug,
117 Info,
118 Warn,
119 Error,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
124pub enum LogFormat {
125 Json,
126 Text,
127 Combined,
128 Common,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct CompressionConfig {
134 pub enabled: bool,
136
137 pub algorithms: Vec<CompressionAlgorithm>,
139
140 pub min_size: usize,
142
143 pub level: u32,
145
146 pub content_types: Vec<String>,
148}
149
150#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
152pub enum CompressionAlgorithm {
153 Gzip,
154 Deflate,
155 Brotli,
156 Zstd,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct RateLimitConfig {
162 pub enabled: bool,
164
165 pub default_limits: RateLimits,
167
168 pub client_limits: HashMap<String, RateLimits>,
170
171 pub storage: RateLimitStorage,
173
174 pub include_headers: bool,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct RateLimits {
181 pub requests_per_minute: u32,
183
184 pub requests_per_hour: u32,
186
187 pub tokens_per_minute: u32,
189
190 pub tokens_per_hour: u32,
192
193 pub concurrent_requests: u32,
195}
196
197#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
199pub enum RateLimitStorage {
200 Memory,
201 Redis,
202 Database,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct TimeoutConfig {
208 pub enabled: bool,
210
211 pub request_timeout: Duration,
213
214 pub keep_alive_timeout: Duration,
216
217 pub read_timeout: Duration,
219
220 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}