From 65d2df795fa4010d29384d91f21de583af8d9058 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 22 Sep 2026 09:38:52 +0200 Subject: [PATCH] http1: keep monotonic progress for 100-continue Ticket: 9096 In case of a 100-continue response, we used to - parse the response line, set progress to headers - parse headers, set progress back to line This caused FPs as the engine expects the progress to just increase so that it skips signatures that did not match yet, and whose progress is less than the tx progress. Solution is to keep progress at line when we see a 100 response, until we get to the body, or after a next response line which is not 100. --- rust/htp/src/response.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/rust/htp/src/response.rs b/rust/htp/src/response.rs index 19070ad93c..868f7d478e 100644 --- a/rust/htp/src/response.rs +++ b/rust/htp/src/response.rs @@ -80,9 +80,9 @@ impl ConnectionParser { input.reset_callback_start(); match resp.response_progress { - HtpResponseProgress::HEADERS => self.response_receiver_set(header_fn), HtpResponseProgress::TRAILER => self.response_receiver_set(trailer_fn), - _ => Ok(()), + // response_state == State::Headers can have progress LINE after a 100 continue + _ => self.response_receiver_set(header_fn), }?; } // Same comment as in request_handle_state_change(). Below is a copy. @@ -465,7 +465,6 @@ impl ConnectionParser { let response_tx = self.response_mut().unwrap(); // Ignore any response headers seen so far. response_tx.response_headers.elements.clear(); - response_tx.response_progress = HtpResponseProgress::LINE; response_tx.seen_100continue = true; return Ok(()); } @@ -729,7 +728,12 @@ impl ConnectionParser { self.state_response_line()?; // Move on to the next phase. self.response_state = State::Headers; - self.response_mut().unwrap().response_progress = HtpResponseProgress::HEADERS; + let response_tx = self.response_mut().unwrap(); + // delay progress in case of a 100 continue + // so we do not revert progress to line after headers + if !response_tx.response_status_number.eq_num(100) { + response_tx.response_progress = HtpResponseProgress::HEADERS; + } Ok(()) } @@ -1013,7 +1017,8 @@ impl ConnectionParser { } // We've seen all response headers. At terminator. self.response_state = - if self.response().unwrap().response_progress == HtpResponseProgress::HEADERS { + // we can have response progress LINE in case of 100 continue + if self.response().unwrap().response_progress <= HtpResponseProgress::HEADERS { // Response headers. // The next step is to determine if this response has a body. State::BodyDetermine