Spaces:
Running
Running
| // Request/Response validation middleware for FAANG-level safety | |
| use std::sync::atomic::{AtomicUsize, Ordering}; | |
| use std::sync::Arc; | |
| /// Tracks concurrent requests per client IP | |
| pub struct ConcurrencyLimiter { | |
| max_concurrent: usize, | |
| active_requests: Arc<AtomicUsize>, | |
| } | |
| impl ConcurrencyLimiter { | |
| pub fn new(max_concurrent: usize) -> Self { | |
| Self { | |
| max_concurrent, | |
| active_requests: Arc::new(AtomicUsize::new(0)), | |
| } | |
| } | |
| pub fn can_accept(&self) -> bool { | |
| let current = self.active_requests.load(Ordering::SeqCst); | |
| current < self.max_concurrent | |
| } | |
| pub fn increment(&self) { | |
| self.active_requests.fetch_add(1, Ordering::SeqCst); | |
| } | |
| pub fn decrement(&self) { | |
| self.active_requests.fetch_sub(1, Ordering::SeqCst); | |
| } | |
| } | |
| /// Request timeout guard for external API calls | |
| pub struct TimeoutGuard { | |
| timeout_secs: u64, | |
| } | |
| impl TimeoutGuard { | |
| pub fn new(timeout_secs: u64) -> Self { | |
| Self { timeout_secs } | |
| } | |
| pub fn create_timeout(&self) -> std::time::Duration { | |
| std::time::Duration::from_secs(self.timeout_secs) | |
| } | |
| } | |
| /// Request size validator | |
| pub fn validate_request_body_size(size: usize, max_bytes: usize) -> Result<(), String> { | |
| if size > max_bytes { | |
| return Err(format!( | |
| "Request body too large: {} bytes (max: {} bytes)", | |
| size, max_bytes | |
| )); | |
| } | |
| Ok(()) | |
| } | |
| /// Validate response consistency for critical operations | |
| pub fn validate_response_consistency( | |
| rows_affected: u64, | |
| expected_count: u64, | |
| ) -> Result<(), String> { | |
| if rows_affected != expected_count { | |
| return Err(format!( | |
| "Data consistency check failed: affected {} rows, expected {}", | |
| rows_affected, expected_count | |
| )); | |
| } | |
| Ok(()) | |
| } | |
| mod tests { | |
| use super::*; | |
| fn test_concurrency_limiter() { | |
| let limiter = ConcurrencyLimiter::new(2); | |
| assert!(limiter.can_accept()); | |
| limiter.increment(); | |
| assert!(limiter.can_accept()); | |
| limiter.increment(); | |
| assert!(!limiter.can_accept()); | |
| limiter.decrement(); | |
| assert!(limiter.can_accept()); | |
| } | |
| fn test_request_size_validation() { | |
| assert!(validate_request_body_size(100, 1000).is_ok()); | |
| assert!(validate_request_body_size(2000, 1000).is_err()); | |
| } | |
| fn test_response_consistency() { | |
| assert!(validate_response_consistency(1, 1).is_ok()); | |
| assert!(validate_response_consistency(1, 2).is_err()); | |
| } | |
| } | |