From 834cb9619e61af1172fe34e914fd0a132a0a1db6 Mon Sep 17 00:00:00 2001 From: Dany LE Date: Thu, 9 Apr 2026 15:59:41 +0200 Subject: [PATCH] fix: dont panic when unable to accept client connection --- src/main.rs | 55 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index 87b3d9f..d508d67 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,6 +66,38 @@ fn handle_request(mut stream: T) { DEBUG!("Request on socket {} is processed", stream.as_raw_fd()); } +trait Listener { + type Stream: Read + Write + AsRawFd + Send + 'static; + fn incoming(&self) -> Box> + '_>; + + fn dispatch(&self, pool: &ThreadPool) { + for client in self.incoming() { + if let Ok(stream) = client { + pool.execute(move || handle_request(stream)); + } else { + ERROR!( + "Unable to accept client connection: {}", + client.err().unwrap() + ); + } + } + } +} + +impl Listener for UnixListener { + type Stream = std::os::unix::net::UnixStream; + fn incoming(&self) -> Box> + '_> { + Box::new(self.incoming()) + } +} + +impl Listener for TcpListener { + type Stream = std::net::TcpStream; + fn incoming(&self) -> Box> + '_> { + Box::new(self.incoming()) + } +} + /// Start the `fastCGI` server /// /// # Arguments @@ -87,19 +119,12 @@ fn serve(config: &Config) { if let Err(error) = chmod_file(&path, 0o660) { ERROR!("Unable to allow writable for group on {}: {}", path, error); } - - for client in listener.incoming() { - let stream = client.unwrap(); - pool.execute(move || handle_request(stream)); - } + listener.dispatch(&pool); } else { // TCP socket eg. 127.0.0.1:9000 INFO!("Use TCP socket: {}", socket_name); let listener = TcpListener::bind(socket_name).unwrap(); - for client in listener.incoming() { - let stream = client.unwrap(); - pool.execute(move || handle_request(stream)); - } + listener.dispatch(&pool); } } else { // if there is no socket configuration, assume that the stdio is already mapped @@ -110,19 +135,11 @@ fn serve(config: &Config) { if is_unix_socket(fd).unwrap() { DEBUG!("Stdin is used as Unix domain socket"); let listener = unsafe { UnixListener::from_raw_fd(stdin.as_raw_fd()) }; - for client in listener.incoming() { - let stream = client.unwrap(); - - pool.execute(move || handle_request(stream)); - } + listener.dispatch(&pool); } else { DEBUG!("Stdin is used as TCP Socket"); let listener = unsafe { TcpListener::from_raw_fd(stdin.as_raw_fd()) }; - for client in listener.incoming() { - let stream = client.unwrap(); - - pool.execute(move || handle_request(stream)); - } + listener.dispatch(&pool); } } }