Previously, filters and post-filters were checked even if pre-filter has set some result. Now pre-result efficienly makes a trapdoor to writing reply (as it was before 1.0).tags/1.3.0
@@ -346,23 +346,41 @@ enum rspamd_metric_action | |||
rspamd_check_action_metric (struct rspamd_task *task, struct metric_result *mres) | |||
{ | |||
struct metric_action *action, *selected_action = NULL; | |||
double max_score = 0; | |||
double max_score = 0, sc; | |||
int i; | |||
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { | |||
double sc; | |||
if (task->pre_result.action == METRIC_ACTION_MAX) { | |||
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { | |||
action = &mres->metric->actions[i]; | |||
sc = mres->actions_limits[i]; | |||
action = &mres->metric->actions[i]; | |||
sc = mres->actions_limits[i]; | |||
if (isnan (sc)) { | |||
continue; | |||
} | |||
if (isnan (sc)) { | |||
continue; | |||
if (mres->score >= sc && sc > max_score) { | |||
selected_action = action; | |||
max_score = sc; | |||
} | |||
} | |||
} | |||
else { | |||
i = task->pre_result.action; | |||
selected_action = &mres->metric->actions[i]; | |||
sc = mres->actions_limits[i]; | |||
while (isnan (sc)) { | |||
i = (i + 1) % METRIC_ACTION_MAX; | |||
sc = mres->actions_limits[i]; | |||
if (mres->score >= sc && sc > max_score) { | |||
selected_action = action; | |||
max_score = sc; | |||
if (i == task->pre_result.action) { | |||
/* No scores defined, just avoid NaN */ | |||
sc = 0; | |||
break; | |||
} | |||
} | |||
mres->score = sc; | |||
} | |||
if (selected_action) { |
@@ -98,7 +98,7 @@ rspamd_task_new (struct rspamd_worker *worker, struct rspamd_config *cfg) | |||
new_task->sock = -1; | |||
new_task->flags |= (RSPAMD_TASK_FLAG_MIME|RSPAMD_TASK_FLAG_JSON); | |||
new_task->pre_result.action = METRIC_ACTION_NOACTION; | |||
new_task->pre_result.action = METRIC_ACTION_MAX; | |||
new_task->message_id = new_task->queue_id = "undef"; | |||
@@ -448,6 +448,13 @@ rspamd_task_process (struct rspamd_task *task, guint stages) | |||
case RSPAMD_TASK_STAGE_PRE_FILTERS: | |||
rspamd_lua_call_pre_filters (task); | |||
if (task->pre_result.action != METRIC_ACTION_MAX) { | |||
/* Skip all if we have result here */ | |||
task->processed_stages |= RSPAMD_TASK_STAGE_DONE; | |||
msg_info_task ("skip filters, as pre-filter returned %s action", | |||
rspamd_action_to_str (task->pre_result.action)); | |||
} | |||
break; | |||
case RSPAMD_TASK_STAGE_FILTERS: |
@@ -178,7 +178,7 @@ struct rspamd_task { | |||
gpointer checkpoint; /**< Opaque checkpoint data */ | |||
struct { | |||
guint32 action; /**< Action of pre filters */ | |||
gint action; /**< Action of pre filters */ | |||
gchar *str; /**< String describing action */ | |||
} pre_result; /**< Result of pre-filters */ | |||
@@ -779,6 +779,12 @@ rspamd_lua_call_pre_filters (struct rspamd_task *task) | |||
lua_tostring (cd->L, -1)); | |||
lua_pop (cd->L, 1); | |||
} | |||
if (task->pre_result.action != METRIC_ACTION_MAX) { | |||
/* Stop processing on reaching some pre-result */ | |||
break; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
} |