use std::env; /// Server configuration loaded from environment variables with sensible defaults. #[derive(Debug, Clone)] pub struct Config { /// Bind address (default: 0.0.0.0) pub host: String, /// Bind port (default: 8080) pub port: u16, /// Allowed CORS origins. "*" permits everything (dev mode). pub cors_origins: Vec, /// Maximum concurrent sessions (default: 100) pub max_sessions: usize, /// Seconds before an idle session is reaped (default: 300) pub idle_timeout_secs: u64, /// Max display-frame buffer depth per session (default: 60 ≈ 2 s @ 30 fps) pub frame_buffer_size: usize, } impl Config { /// Build configuration from `BUTTERFLY_*` env vars, falling back to defaults. pub fn from_env() -> Self { Self { host: env::var("BUTTERFLY_HOST").unwrap_or_else(|_| "0.0.0.0".into()), port: env::var("BUTTERFLY_PORT") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(8080), cors_origins: env::var("BUTTERFLY_CORS_ORIGINS") .map(|v| v.split(',').map(|s| s.trim().to_string()).collect()) .unwrap_or_else(|_| vec!["*".into()]), max_sessions: env::var("BUTTERFLY_MAX_SESSIONS") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(100), idle_timeout_secs: env::var("BUTTERFLY_IDLE_TIMEOUT") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(300), frame_buffer_size: env::var("BUTTERFLY_FRAME_BUFFER") .ok() .and_then(|v| v.parse().ok()) .unwrap_or(60), } } /// Address string suitable for `bind()`, e.g. "0.0.0.0:8080". pub fn bind_addr(&self) -> String { format!("{}:{}", self.host, self.port) } }