From 1ad6c5a49bf70df4554bbceff6ae1a8229bf1b56 Mon Sep 17 00:00:00 2001 From: Rudi Floren Date: Thu, 19 Feb 2026 15:31:32 +0100 Subject: [PATCH] fix stuck in read state The state machine for reading uses three states. `Writing`, `Read Length` and `Reading`. Read length will set up the reading state with the expected length and the already read bytes (header). In the reading state, if not enough bytes have been read from the connection, the state machine stays in the reading state. The reading state failed to return the proper state. It reused the `state` var and thus never propagated the updated read var (which is owned in the scope). Everytime, the loop entered the transition from the `Reading` state, `read` was fixed to the initialized value from the `Reading Length` state. This caused the connection to be stuck for large responses (for example a `` with over 20 domains). We now emit a new `Reading` state with updated values. --- src/connection.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index 9ef21f2..9c6b451 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -10,7 +10,7 @@ use std::{io, mem, str}; use async_trait::async_trait; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadBuf}; -use tracing::{debug, info}; +use tracing::{debug, info, trace}; use crate::error::Error; @@ -205,12 +205,19 @@ impl EppConnection { read, expected ); + // str::from_utf8 will only be executed when the trace callsite is enabled. + // E.g. a tracing-subscriber listens for trace-level events. + trace!("Read: {}", str::from_utf8(filled).unwrap_or("")); // Ok(if read < *expected { - // If we haven't received the entire response yet, stick to the `Reading` state. - Transition::Next(state) + // If we haven't received the entire response yet, stick to the `Reading` state with updatead values. + Transition::Next(RequestState::Reading { + read, + buf: mem::take(buf), + expected: *expected, + }) } else if let Some(next) = self.next.take() { // Otherwise, if we were just pushing through this request because it was already // in flight when we started a new one, ignore this response and move to the