http1: do not re-parse Content-Disposition header

Ticket: 8529

When Suricata handles a HTTP1 response body, it does so with a
file, and tries to get the filename from the Content-Disposition
header if any, then from the uri.

If it failed to find a file name, it tried again every time
there was new data from the response body, even if there was
no new data to find a file name in either the header nor the uri.

This causes a slowdown in the case the Content-Disposition header
is big.

Fix is to set the flag on the first call of the callback, to be
sure that we will parse the Content-Disposition header for a
filename header only once per http1 response.
This commit is contained in:
Philippe Antoine 2026-05-03 22:44:31 +02:00 committed by Victor Julien
parent 6d437956e2
commit 9aaa6f7854
2 changed files with 6 additions and 1 deletions

View file

@ -1270,7 +1270,11 @@ static int HtpResponseBodyHandle(HtpState *hstate, HtpTxUserData *htud, const ht
* we check for htp_tx_response_line(tx) in case of junk
* interpreted as body before response line
*/
if (!(htud->tcflags & HTP_FILENAME_SET)) {
if (!(htud->tcflags & HTP_RESP_BODY_SEEN)) {
// make sure we run this only once per tx
// so that we do not retry/refail to parse Content-Disposition header
// which may be expensive if we do it for every packet...
htud->tcflags |= HTP_RESP_BODY_SEEN;
SCLogDebug("setting up file name");
const uint8_t *filename = NULL;

View file

@ -146,6 +146,7 @@ typedef struct HtpBody_ {
#define HTP_FILENAME_SET BIT_U8(3) /**< filename is registered in the flow */
#define HTP_DONTSTORE BIT_U8(4) /**< not storing this file */
#define HTP_STREAM_DEPTH_SET BIT_U8(5) /**< stream-depth is set */
#define HTP_RESP_BODY_SEEN BIT_U8(6) /**< response body was seen at least once */
/** Now the Body Chunks will be stored per transaction, at
* the tx user data */