From c0efcf559db09cd76bb654d5f79b4f3517e4bb12 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Wed, 18 Feb 2026 21:02:48 +0100 Subject: [PATCH] detect/http2: use ThreadCtx for http.header Instead of custom inefficient "escaped" Vec Ticket: 8291 (cherry picked from commit 711de8a5eacb628a6497f5e81a557df128b605bf) --- rust/src/http2/detect.rs | 22 +++++++++++----------- src/detect-http-header.c | 8 +++++++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs index 040c87e7e0..0f32b8cb13 100644 --- a/rust/src/http2/detect.rs +++ b/rust/src/http2/detect.rs @@ -823,8 +823,10 @@ fn http2_header_trimspaces(value: &[u8]) -> &[u8] { #[no_mangle] pub unsafe extern "C" fn SCHttp2TxGetHeaders( tx: &mut HTTP2Transaction, direction: u8, buffer: *mut *const u8, buffer_len: *mut u32, + tbuf: *mut c_void, ) -> u8 { - let mut vec = Vec::new(); + let tbuf = cast_pointer!(tbuf, Http2ThreadBuf); + tbuf.data = Vec::new(); let frames = if direction & Direction::ToServer as u8 != 0 { &tx.frames_ts } else { @@ -835,20 +837,18 @@ pub unsafe extern "C" fn SCHttp2TxGetHeaders( for block in blocks.iter() { if !http2_header_iscookie(direction.into(), &block.name) { // we do not escape linefeeds nor : in headers names - vec.extend_from_slice(&block.name); - vec.extend_from_slice(b": "); - vec.extend_from_slice(http2_header_trimspaces(&block.value)); - vec.extend_from_slice(b"\r\n"); + tbuf.data.extend_from_slice(&block.name); + tbuf.data.extend_from_slice(b": "); + tbuf.data + .extend_from_slice(http2_header_trimspaces(&block.value)); + tbuf.data.extend_from_slice(b"\r\n"); } } } } - if !vec.is_empty() { - tx.escaped.push(vec); - let idx = tx.escaped.len() - 1; - let value = &tx.escaped[idx]; - *buffer = value.as_ptr(); //unsafe - *buffer_len = value.len() as u32; + if !tbuf.data.is_empty() { + *buffer = tbuf.data.as_ptr(); //unsafe + *buffer_len = tbuf.data.len() as u32; return 1; } return 0; diff --git a/src/detect-http-header.c b/src/detect-http-header.c index e3e2d00308..54d27b58cc 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -64,6 +64,7 @@ static void DetectHttpHeaderRegisterTests(void); #endif static int g_http_header_buffer_id = 0; static int g_keyword_thread_id = 0; +static int g_http2_thread_id = 0; #define BUFFER_SIZE_STEP 1024 static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP }; @@ -152,7 +153,10 @@ static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx, uint32_t b_len = 0; const uint8_t *b = NULL; - if (SCHttp2TxGetHeaders(txv, flow_flags, &b, &b_len) != 1) + void *thread_buf = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id); + if (thread_buf == NULL) + return NULL; + if (SCHttp2TxGetHeaders(txv, flow_flags, &b, &b_len, thread_buf) != 1) return NULL; if (b == NULL || b_len == 0) return NULL; @@ -453,6 +457,8 @@ void DetectHttpHeaderRegister(void) g_keyword_thread_id = DetectRegisterThreadCtxGlobalFuncs("http_header", HttpHeaderThreadDataInit, &g_td_config, HttpHeaderThreadDataFree); + g_http2_thread_id = DetectRegisterThreadCtxGlobalFuncs( + "http2.header", SCHttp2ThreadBufDataInit, NULL, SCHttp2ThreadBufDataFree); } static int g_http_request_header_buffer_id = 0;