torch_web/
config.rs

1//! Configuration system for Torch framework
2
3#[cfg(feature = "config")]
4use std::path::Path;
5use std::time::Duration;
6
7#[cfg(feature = "config")]
8use serde::{Deserialize, Serialize};
9
10/// Main configuration structure for Torch applications
11#[derive(Debug, Clone)]
12#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
13pub struct TorchConfig {
14    /// Server configuration
15    pub server: ServerConfig,
16    /// Security configuration
17    pub security: SecurityConfig,
18    /// Monitoring and logging configuration
19    pub monitoring: MonitoringConfig,
20    /// Performance configuration
21    pub performance: PerformanceConfig,
22    /// Rate limiting configuration
23    pub rate_limiting: RateLimitingConfig,
24    /// Database configuration
25    pub database: Option<DatabaseConfig>,
26    /// Custom application settings
27    #[cfg_attr(feature = "config", serde(default))]
28    pub custom: std::collections::HashMap<String, String>,
29}
30
31/// Server configuration
32#[derive(Debug, Clone)]
33#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
34pub struct ServerConfig {
35    /// Server host address
36    pub host: String,
37    /// Server port
38    pub port: u16,
39    /// Maximum number of concurrent connections
40    pub max_connections: usize,
41    /// Request timeout in seconds
42    pub request_timeout_secs: u64,
43    /// Keep-alive timeout in seconds
44    pub keep_alive_timeout_secs: u64,
45    /// Maximum request body size in bytes
46    pub max_body_size: usize,
47    /// Number of worker threads (None = auto-detect)
48    pub worker_threads: Option<usize>,
49    /// Enable HTTP/2
50    pub enable_http2: bool,
51    /// Enable TLS/SSL
52    pub enable_tls: bool,
53    /// TLS certificate file path
54    pub tls_cert_path: Option<String>,
55    /// TLS private key file path
56    pub tls_key_path: Option<String>,
57    /// Graceful shutdown timeout in seconds
58    pub graceful_shutdown_timeout_secs: u64,
59}
60
61/// Security configuration
62#[derive(Debug, Clone)]
63#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
64pub struct SecurityConfig {
65    /// Enable CORS
66    pub enable_cors: bool,
67    /// CORS allowed origins
68    pub cors_allowed_origins: Vec<String>,
69    /// CORS allowed methods
70    pub cors_allowed_methods: Vec<String>,
71    /// CORS allowed headers
72    pub cors_allowed_headers: Vec<String>,
73    /// Enable security headers
74    pub enable_security_headers: bool,
75    /// Content Security Policy
76    pub content_security_policy: Option<String>,
77    /// Enable request signing verification
78    pub enable_request_signing: bool,
79    /// Secret key for request signing
80    pub signing_secret: Option<String>,
81    /// Enable IP whitelisting
82    pub enable_ip_whitelist: bool,
83    /// Whitelisted IP addresses/ranges
84    pub ip_whitelist: Vec<String>,
85    /// Enable request ID tracking
86    pub enable_request_id: bool,
87    /// Maximum request size for security
88    pub max_request_size: usize,
89    /// Enable input validation
90    pub enable_input_validation: bool,
91    /// SQL injection protection
92    pub enable_sql_injection_protection: bool,
93    /// XSS protection
94    pub enable_xss_protection: bool,
95}
96
97/// Monitoring and logging configuration
98#[derive(Debug, Clone)]
99#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
100pub struct MonitoringConfig {
101    /// Enable request logging
102    pub enable_request_logging: bool,
103    /// Log level (error, warn, info, debug, trace)
104    pub log_level: String,
105    /// Log format (json, text)
106    pub log_format: String,
107    /// Log file path (None = stdout)
108    pub log_file: Option<String>,
109    /// Enable metrics collection
110    pub enable_metrics: bool,
111    /// Metrics endpoint path
112    pub metrics_endpoint: String,
113    /// Enable health check endpoint
114    pub enable_health_check: bool,
115    /// Health check endpoint path
116    pub health_check_endpoint: String,
117    /// Enable performance monitoring
118    pub enable_performance_monitoring: bool,
119    /// Slow request threshold in milliseconds
120    pub slow_request_threshold_ms: u64,
121    /// Enable error tracking
122    pub enable_error_tracking: bool,
123    /// Error tracking service URL
124    pub error_tracking_url: Option<String>,
125    /// Enable distributed tracing
126    pub enable_distributed_tracing: bool,
127    /// Tracing service endpoint
128    pub tracing_endpoint: Option<String>,
129}
130
131/// Performance configuration
132#[derive(Debug, Clone)]
133#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
134pub struct PerformanceConfig {
135    /// Enable response compression
136    pub enable_compression: bool,
137    /// Compression level (1-9)
138    pub compression_level: u8,
139    /// Enable response caching
140    pub enable_caching: bool,
141    /// Cache TTL in seconds
142    pub cache_ttl_secs: u64,
143    /// Maximum cache size in MB
144    pub max_cache_size_mb: usize,
145    /// Enable connection pooling
146    pub enable_connection_pooling: bool,
147    /// Connection pool size
148    pub connection_pool_size: usize,
149    /// Connection pool timeout in seconds
150    pub connection_pool_timeout_secs: u64,
151    /// Enable keep-alive
152    pub enable_keep_alive: bool,
153    /// Keep-alive timeout in seconds
154    pub keep_alive_timeout_secs: u64,
155}
156
157/// Rate limiting configuration
158#[derive(Debug, Clone)]
159#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
160pub struct RateLimitingConfig {
161    /// Enable rate limiting
162    pub enable_rate_limiting: bool,
163    /// Global requests per second limit
164    pub global_rps_limit: Option<u32>,
165    /// Per-IP requests per second limit
166    pub per_ip_rps_limit: Option<u32>,
167    /// Per-user requests per second limit
168    pub per_user_rps_limit: Option<u32>,
169    /// Rate limiting window in seconds
170    pub window_secs: u64,
171    /// Enable burst allowance
172    pub enable_burst: bool,
173    /// Burst size
174    pub burst_size: u32,
175    /// Rate limiting storage backend (memory, redis)
176    pub storage_backend: String,
177    /// Redis URL for distributed rate limiting
178    pub redis_url: Option<String>,
179}
180
181/// Database configuration
182#[derive(Debug, Clone)]
183#[cfg_attr(feature = "config", derive(Serialize, Deserialize))]
184pub struct DatabaseConfig {
185    /// Database URL
186    pub url: String,
187    /// Maximum number of connections
188    pub max_connections: u32,
189    /// Minimum number of connections
190    pub min_connections: u32,
191    /// Connection timeout in seconds
192    pub connect_timeout_secs: u64,
193    /// Query timeout in seconds
194    pub query_timeout_secs: u64,
195    /// Enable connection pooling
196    pub enable_pooling: bool,
197    /// Enable query logging
198    pub enable_query_logging: bool,
199    /// Enable migrations
200    pub enable_migrations: bool,
201    /// Migrations directory
202    pub migrations_dir: Option<String>,
203}
204
205impl Default for TorchConfig {
206    fn default() -> Self {
207        Self {
208            server: ServerConfig::default(),
209            security: SecurityConfig::default(),
210            monitoring: MonitoringConfig::default(),
211            performance: PerformanceConfig::default(),
212            rate_limiting: RateLimitingConfig::default(),
213            database: None,
214            custom: std::collections::HashMap::new(),
215        }
216    }
217}
218
219impl Default for ServerConfig {
220    fn default() -> Self {
221        Self {
222            host: "127.0.0.1".to_string(),
223            port: 3000,
224            max_connections: 10_000,
225            request_timeout_secs: 30,
226            keep_alive_timeout_secs: 60,
227            max_body_size: 16 * 1024 * 1024, // 16MB
228            worker_threads: None,
229            enable_http2: true,
230            enable_tls: false,
231            tls_cert_path: None,
232            tls_key_path: None,
233            graceful_shutdown_timeout_secs: 30,
234        }
235    }
236}
237
238impl Default for SecurityConfig {
239    fn default() -> Self {
240        Self {
241            enable_cors: true,
242            cors_allowed_origins: vec!["*".to_string()],
243            cors_allowed_methods: vec![
244                "GET".to_string(),
245                "POST".to_string(),
246                "PUT".to_string(),
247                "DELETE".to_string(),
248                "OPTIONS".to_string(),
249            ],
250            cors_allowed_headers: vec![
251                "Content-Type".to_string(),
252                "Authorization".to_string(),
253                "X-Requested-With".to_string(),
254            ],
255            enable_security_headers: true,
256            content_security_policy: Some(
257                "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
258                    .to_string(),
259            ),
260            enable_request_signing: false,
261            signing_secret: None,
262            enable_ip_whitelist: false,
263            ip_whitelist: Vec::new(),
264            enable_request_id: true,
265            max_request_size: 16 * 1024 * 1024, // 16MB
266            enable_input_validation: true,
267            enable_sql_injection_protection: true,
268            enable_xss_protection: true,
269        }
270    }
271}
272
273impl Default for MonitoringConfig {
274    fn default() -> Self {
275        Self {
276            enable_request_logging: true,
277            log_level: "info".to_string(),
278            log_format: "json".to_string(),
279            log_file: None,
280            enable_metrics: true,
281            metrics_endpoint: "/metrics".to_string(),
282            enable_health_check: true,
283            health_check_endpoint: "/health".to_string(),
284            enable_performance_monitoring: true,
285            slow_request_threshold_ms: 1000,
286            enable_error_tracking: true,
287            error_tracking_url: None,
288            enable_distributed_tracing: false,
289            tracing_endpoint: None,
290        }
291    }
292}
293
294impl Default for PerformanceConfig {
295    fn default() -> Self {
296        Self {
297            enable_compression: true,
298            compression_level: 6,
299            enable_caching: true,
300            cache_ttl_secs: 300, // 5 minutes
301            max_cache_size_mb: 100,
302            enable_connection_pooling: true,
303            connection_pool_size: 100,
304            connection_pool_timeout_secs: 30,
305            enable_keep_alive: true,
306            keep_alive_timeout_secs: 60,
307        }
308    }
309}
310
311impl Default for RateLimitingConfig {
312    fn default() -> Self {
313        Self {
314            enable_rate_limiting: true,
315            global_rps_limit: Some(10_000),
316            per_ip_rps_limit: Some(100),
317            per_user_rps_limit: Some(1000),
318            window_secs: 60,
319            enable_burst: true,
320            burst_size: 10,
321            storage_backend: "memory".to_string(),
322            redis_url: None,
323        }
324    }
325}
326
327impl TorchConfig {
328    /// Load configuration from a TOML file
329    #[cfg(feature = "config")]
330    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
331        let content = std::fs::read_to_string(path)?;
332        let config: TorchConfig = toml::from_str(&content)?;
333        Ok(config)
334    }
335
336    /// Save configuration to a TOML file
337    #[cfg(feature = "config")]
338    pub fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), Box<dyn std::error::Error>> {
339        let content = toml::to_string_pretty(self)?;
340        std::fs::write(path, content)?;
341        Ok(())
342    }
343
344    /// Load configuration from environment variables
345    pub fn from_env() -> Self {
346        let mut config = Self::default();
347        
348        // Server configuration
349        if let Ok(host) = std::env::var("TORCH_HOST") {
350            config.server.host = host;
351        }
352        if let Ok(port) = std::env::var("TORCH_PORT") {
353            if let Ok(port) = port.parse() {
354                config.server.port = port;
355            }
356        }
357        if let Ok(max_conn) = std::env::var("TORCH_MAX_CONNECTIONS") {
358            if let Ok(max_conn) = max_conn.parse() {
359                config.server.max_connections = max_conn;
360            }
361        }
362        
363        // Security configuration
364        if let Ok(enable_cors) = std::env::var("TORCH_ENABLE_CORS") {
365            config.security.enable_cors = enable_cors.parse().unwrap_or(true);
366        }
367        if let Ok(secret) = std::env::var("TORCH_SIGNING_SECRET") {
368            config.security.signing_secret = Some(secret);
369            config.security.enable_request_signing = true;
370        }
371        
372        // Add more environment variable mappings as needed
373        
374        config
375    }
376
377    /// Get server address as string
378    pub fn server_address(&self) -> String {
379        format!("{}:{}", self.server.host, self.server.port)
380    }
381
382    /// Get request timeout as Duration
383    pub fn request_timeout(&self) -> Duration {
384        Duration::from_secs(self.server.request_timeout_secs)
385    }
386
387    /// Get keep-alive timeout as Duration
388    pub fn keep_alive_timeout(&self) -> Duration {
389        Duration::from_secs(self.server.keep_alive_timeout_secs)
390    }
391
392    /// Get graceful shutdown timeout as Duration
393    pub fn graceful_shutdown_timeout(&self) -> Duration {
394        Duration::from_secs(self.server.graceful_shutdown_timeout_secs)
395    }
396}