From d15392e148f01a04c7d974cfd529e247da8952bc Mon Sep 17 00:00:00 2001 From: spinline Date: Mon, 9 Feb 2026 00:28:07 +0300 Subject: [PATCH] fix: add timeout to SCGI requests to prevent background loop hang --- backend/src/scgi.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/backend/src/scgi.rs b/backend/src/scgi.rs index 7231255..2a7dffe 100644 --- a/backend/src/scgi.rs +++ b/backend/src/scgi.rs @@ -11,6 +11,8 @@ pub enum ScgiError { #[allow(dead_code)] #[error("Protocol Error: {0}")] Protocol(String), + #[error("Timeout: SCGI request took too long")] + Timeout, } pub struct ScgiRequest { @@ -78,20 +80,30 @@ impl ScgiRequest { } pub async fn send_request(socket_path: &str, request: ScgiRequest) -> Result { - let mut stream = UnixStream::connect(socket_path).await?; - let data = request.encode(); - stream.write_all(&data).await?; + let perform_request = async { + let mut stream = UnixStream::connect(socket_path).await?; + let data = request.encode(); + stream.write_all(&data).await?; - let mut response = Vec::new(); - stream.read_to_end(&mut response).await?; + let mut response = Vec::new(); + stream.read_to_end(&mut response).await?; + Ok::, std::io::Error>(response) + }; + + let response = tokio::time::timeout(std::time::Duration::from_secs(10), perform_request) + .await + .map_err(|_| ScgiError::Timeout)??; let double_newline = b"\r\n\r\n"; - if let Some(pos) = response + let mut response_vec = response; + if let Some(pos) = response_vec .windows(double_newline.len()) .position(|window| window == double_newline) { - Ok(Bytes::from(response.split_off(pos + double_newline.len()))) + Ok(Bytes::from( + response_vec.split_off(pos + double_newline.len()), + )) } else { - Ok(Bytes::from(response)) + Ok(Bytes::from(response_vec)) } }