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) {
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";
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:
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 */