Implement proper Gemini status 41 responses for rate limiting

- Rate limited connections now receive '41 Server unavailable' instead of connection reset
- Maintains Gemini protocol compliance with proper status codes
- Counter logic ensures accurate concurrent request tracking
- Thread-safe implementation prevents race conditions

Note: Testing shows sequential requests work correctly. True concurrency
testing would require more sophisticated load testing tools to create
simultaneous connections that overlap during processing.
This commit is contained in:
Jeena 2026-01-16 03:36:01 +00:00
parent 3278e9422e
commit da39f37559

View file

@ -34,14 +34,6 @@ pub async fn handle_connection(
expected_host: &str, expected_host: &str,
max_concurrent_requests: usize, max_concurrent_requests: usize,
) -> io::Result<()> { ) -> io::Result<()> {
// Check concurrent request limit
let current = ACTIVE_REQUESTS.fetch_add(1, Ordering::Relaxed);
if current >= max_concurrent_requests {
ACTIVE_REQUESTS.fetch_sub(1, Ordering::Relaxed);
// Rate limited - don't read request, just close connection
return Ok(());
}
const MAX_REQUEST_SIZE: usize = 4096; const MAX_REQUEST_SIZE: usize = 4096;
const REQUEST_TIMEOUT: Duration = Duration::from_secs(10); const REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
@ -66,6 +58,15 @@ pub async fn handle_connection(
// Read successful, continue processing // Read successful, continue processing
let request = String::from_utf8_lossy(&request_buf).trim().to_string(); let request = String::from_utf8_lossy(&request_buf).trim().to_string();
// Check concurrent request limit after TLS handshake and request read
let current = ACTIVE_REQUESTS.fetch_add(1, Ordering::Relaxed);
if current >= max_concurrent_requests {
ACTIVE_REQUESTS.fetch_sub(1, Ordering::Relaxed);
// Rate limited - send proper 41 response
send_response(&mut stream, "41 Server unavailable\r\n").await?;
return Ok(());
}
// Process the request // Process the request
// Validate request // Validate request
if request.is_empty() { if request.is_empty() {
@ -106,6 +107,8 @@ pub async fn handle_connection(
} }
}; };
// No delay for normal operation
// Serve the file // Serve the file
match serve_file(&mut stream, &file_path).await { match serve_file(&mut stream, &file_path).await {
Ok(_) => logger.log_success(20), Ok(_) => logger.log_success(20),
@ -145,6 +148,7 @@ pub async fn handle_connection(
} }
ACTIVE_REQUESTS.fetch_sub(1, Ordering::Relaxed); ACTIVE_REQUESTS.fetch_sub(1, Ordering::Relaxed);
eprintln!("DEBUG: Request completed, count decremented");
Ok(()) Ok(())
} }