mirror of
https://github.com/openappsec/attachment.git
synced 2026-01-02 22:54:50 +03:00
Refactor delayed verdict handling and add configurable retries (#52)
Extract HandleDelayedVerdict() to eliminate duplication and make retry count and polling time configurable. Add delayed verdict handling to SendRequestEnd with unit tests.
This commit is contained in:
@@ -291,6 +291,70 @@ FinalizeFailedResponse(NanoAttachment *attachment, SessionID session_id, HttpEve
|
||||
return response;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Handles delayed verdict by spawning SendDelayedVerdictRequestThread and waiting for the verdict.
|
||||
///
|
||||
/// @param attachment Pointer to the NanoAttachment struct representing the attachment.
|
||||
/// @param data Pointer to the AttachmentData struct containing the attachment data.
|
||||
/// @param session_id The session ID associated with the attachment.
|
||||
/// @param ctx Pointer to the HttpEventThreadCtx struct containing the HTTP event context.
|
||||
/// @param transaction_type The transaction type (REQUEST or RESPONSE).
|
||||
/// @return 1 if timeout occurred (caller should handle timeout response), 0 if successful (continue processing).
|
||||
///
|
||||
static int
|
||||
HandleDelayedVerdict(
|
||||
NanoAttachment *attachment,
|
||||
AttachmentData *data,
|
||||
SessionID session_id,
|
||||
HttpEventThreadCtx *ctx,
|
||||
TransactionType transaction_type
|
||||
)
|
||||
{
|
||||
int res;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < attachment->hold_verdict_retries; i++) {
|
||||
sleep(attachment->hold_verdict_polling_time);
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_DEBUG, "spawn SendDelayedVerdictRequestThread");
|
||||
res = NanoRunInThreadTimeout(
|
||||
attachment,
|
||||
data,
|
||||
SendDelayedVerdictRequestThread,
|
||||
(void *)ctx,
|
||||
attachment->waiting_for_verdict_thread_timeout_msec,
|
||||
"SendDelayedVerdictRequestThread",
|
||||
transaction_type
|
||||
);
|
||||
if (!res) {
|
||||
updateMetricField(attachment, HOLD_THREAD_TIMEOUT, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished SendDelayedVerdictRequestThread successfully. res=%d",
|
||||
ctx->res
|
||||
);
|
||||
|
||||
if (ctx->session_data_p->verdict != TRAFFIC_VERDICT_DELAYED) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_WARNING,
|
||||
"SendDelayedVerdictRequestThread timed out after %d retries",
|
||||
attachment->hold_verdict_retries
|
||||
);
|
||||
|
||||
ctx->res = NANO_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AttachmentVerdictResponse
|
||||
SendRequestFilter(NanoAttachment *attachment, AttachmentData *data)
|
||||
{
|
||||
@@ -446,28 +510,9 @@ SendRequestHeaders(NanoAttachment *attachment, AttachmentData *data)
|
||||
);
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DELAYED) {
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_DEBUG, "spawn SendDelayedVerdictRequestThread");
|
||||
res = NanoRunInThreadTimeout(
|
||||
attachment,
|
||||
data,
|
||||
SendDelayedVerdictRequestThread,
|
||||
(void *)&ctx,
|
||||
attachment->waiting_for_verdict_thread_timeout_msec,
|
||||
"SendDelayedVerdictRequestThread",
|
||||
REQUEST
|
||||
);
|
||||
if (!res) {
|
||||
updateMetricField(attachment, HOLD_THREAD_TIMEOUT, 1);
|
||||
if (HandleDelayedVerdict(attachment, data, session_id, &ctx, REQUEST)) {
|
||||
return SendThreadTimeoutVerdict(attachment, session_id, &ctx);
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished SendDelayedVerdictRequestThread successfully. res=%d",
|
||||
ctx.res
|
||||
);
|
||||
}
|
||||
|
||||
if (ctx.res != NANO_HTTP_FORBIDDEN && ctx.res != NANO_OK) {
|
||||
@@ -567,28 +612,9 @@ SendRequestBody(NanoAttachment *attachment, AttachmentData *data)
|
||||
);
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DELAYED) {
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_DEBUG, "spawn SendDelayedVerdictRequestThread");
|
||||
res = NanoRunInThreadTimeout(
|
||||
attachment,
|
||||
data,
|
||||
SendDelayedVerdictRequestThread,
|
||||
(void *)&ctx,
|
||||
attachment->waiting_for_verdict_thread_timeout_msec,
|
||||
"SendDelayedVerdictRequestThread",
|
||||
REQUEST
|
||||
);
|
||||
if (!res) {
|
||||
updateMetricField(attachment, HOLD_THREAD_TIMEOUT, 1);
|
||||
if (HandleDelayedVerdict(attachment, data, session_id, &ctx, REQUEST)) {
|
||||
return SendThreadTimeoutVerdict(attachment, session_id, &ctx);
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished SendDelayedVerdictRequestThread successfully. res=%d",
|
||||
ctx.res
|
||||
);
|
||||
}
|
||||
|
||||
if (ctx.res != NANO_HTTP_FORBIDDEN && ctx.res != NANO_OK) {
|
||||
@@ -637,28 +663,9 @@ SendResponseBody(NanoAttachment *attachment, AttachmentData *data)
|
||||
);
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DELAYED) {
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_DEBUG, "spawn SendDelayedVerdictRequestThread");
|
||||
res = NanoRunInThreadTimeout(
|
||||
attachment,
|
||||
data,
|
||||
SendDelayedVerdictRequestThread,
|
||||
(void *)&ctx,
|
||||
attachment->waiting_for_verdict_thread_timeout_msec,
|
||||
"SendDelayedVerdictRequestThread",
|
||||
RESPONSE
|
||||
);
|
||||
if (!res) {
|
||||
updateMetricField(attachment, HOLD_THREAD_TIMEOUT, 1);
|
||||
if (HandleDelayedVerdict(attachment, data, session_id, &ctx, RESPONSE)) {
|
||||
return SendThreadTimeoutVerdict(attachment, session_id, &ctx);
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished SendDelayedVerdictRequestThread successfully. res=%d",
|
||||
ctx.res
|
||||
);
|
||||
}
|
||||
|
||||
if (ctx.res != NANO_HTTP_FORBIDDEN && ctx.res != NANO_OK) {
|
||||
@@ -713,28 +720,9 @@ SendRequestEnd(NanoAttachment *attachment, AttachmentData *data)
|
||||
);
|
||||
|
||||
if (session_data_p->verdict == TRAFFIC_VERDICT_DELAYED) {
|
||||
write_dbg(attachment, session_id, DBG_LEVEL_DEBUG, "spawn SendDelayedVerdictRequestThread");
|
||||
res = NanoRunInThreadTimeout(
|
||||
attachment,
|
||||
data,
|
||||
SendDelayedVerdictRequestThread,
|
||||
(void *)&ctx,
|
||||
attachment->waiting_for_verdict_thread_timeout_msec,
|
||||
"SendDelayedVerdictRequestThread",
|
||||
RESPONSE
|
||||
);
|
||||
if (!res) {
|
||||
updateMetricField(attachment, HOLD_THREAD_TIMEOUT, 1);
|
||||
if (HandleDelayedVerdict(attachment, data, session_id, &ctx, REQUEST)) {
|
||||
return SendThreadTimeoutVerdict(attachment, session_id, &ctx);
|
||||
}
|
||||
|
||||
write_dbg(
|
||||
attachment,
|
||||
session_id,
|
||||
DBG_LEVEL_DEBUG,
|
||||
"finished SendDelayedVerdictRequestThread successfully. res=%d",
|
||||
ctx.res
|
||||
);
|
||||
}
|
||||
|
||||
if (ctx.res != NANO_HTTP_FORBIDDEN && ctx.res != NANO_OK) {
|
||||
|
||||
Reference in New Issue
Block a user