Spaces:
Running
Running
File size: 2,615 Bytes
bad8640 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | // Request/Response validation middleware for FAANG-level safety
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
/// Tracks concurrent requests per client IP
#[derive(Clone)]
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(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
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());
}
#[test]
fn test_request_size_validation() {
assert!(validate_request_body_size(100, 1000).is_ok());
assert!(validate_request_body_size(2000, 1000).is_err());
}
#[test]
fn test_response_consistency() {
assert!(validate_response_consistency(1, 1).is_ok());
assert!(validate_response_consistency(1, 2).is_err());
}
}
|