From 94282bc2641d4285964dfbd780c334ba3c67d1e7 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 19 Aug 2014 15:30:24 +0100 Subject: [PATCH] Consider settings actions. --- src/libmime/filter.c | 61 ++++++++++++++++++++++++++---------- src/libmime/filter.h | 5 +-- src/libserver/protocol.c | 13 +++----- src/libserver/roll_history.c | 6 ++-- src/lua/lua_task.c | 4 +-- 5 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/libmime/filter.c b/src/libmime/filter.c index c8273ed65..3f3b26f6a 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -1001,37 +1001,64 @@ str_action_metric (enum rspamd_metric_action action) return "unknown action"; } +static double +get_specific_action_score (const ucl_object_t *metric, + struct metric_action *action) +{ + const ucl_object_t *act, *sact; + double score; + + if (metric) { + act = ucl_object_find_key (metric, "actions"); + if (act) { + sact = ucl_object_find_key (act, str_action_metric (action->action)); + if (sact != NULL && ucl_object_todouble_safe (sact, &score)) { + return score; + } + } + } + + return action->score; +} + gint -check_metric_action (double score, double required_score, struct metric *metric) +check_metric_action (struct rspamd_task *task, + double score, double *rscore, struct metric *metric) { struct metric_action *action, *selected_action = NULL; double max_score = 0; + const ucl_object_t *ms = NULL; int i; - if (score >= required_score) { - return METRIC_ACTION_REJECT; - } - else if (metric->actions == NULL) { - return METRIC_ACTION_NOACTION; - } - else { + if (metric->actions != NULL) { + if (task->settings) { + ms = ucl_object_find_key (task->settings, metric->name); + } + for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { + double sc; + action = &metric->actions[i]; - if (action->score < 0) { + sc = get_specific_action_score (ms, action); + + if (sc < 0) { continue; } - if (score >= action->score && action->score > max_score) { + if (score >= sc && sc > max_score) { selected_action = action; - max_score = action->score; + max_score = sc; + } + + if (rscore != NULL && i == METRIC_ACTION_REJECT) { + *rscore = sc; } - } - if (selected_action) { - return selected_action->action; - } - else { - return METRIC_ACTION_NOACTION; } } + if (selected_action) { + return selected_action->action; + } + + return METRIC_ACTION_NOACTION; } gboolean diff --git a/src/libmime/filter.h b/src/libmime/filter.h index c7ac43951..24b871efe 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -176,8 +176,9 @@ const gchar * str_action_metric (enum rspamd_metric_action action); /* * Get action for specific metric */ -gint check_metric_action (double score, - double required_score, +gint check_metric_action (struct rspamd_task *task, + double score, + double *rscore, struct metric *metric); #endif diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 38d6452cf..2e9e9c9e7 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -625,18 +625,17 @@ rspamd_metric_result_ucl (struct rspamd_task *task, struct metric *m; gboolean is_spam; enum rspamd_metric_action action = METRIC_ACTION_NOACTION; - ucl_object_t *obj = NULL, *sobj; - gdouble required_score; + ucl_object_t *obj = NULL, *sobj;; gpointer h, v; + double required_score; const gchar *subject; gchar action_char; m = mres->metric; /* XXX: handle settings */ - required_score = m->actions[METRIC_ACTION_REJECT].score; - is_spam = (mres->score >= required_score); - action = check_metric_action (mres->score, required_score, m); + action = check_metric_action (task, mres->score, &required_score, m); + is_spam = (action == METRIC_ACTION_REJECT); if (task->is_skipped) { action_char = 'S'; } @@ -822,9 +821,7 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, /* Update stat for default metric */ metric_res = g_hash_table_lookup (task->results, DEFAULT_METRIC); if (metric_res != NULL) { - required_score = - metric_res->metric->actions[METRIC_ACTION_REJECT].score; - action = check_metric_action (metric_res->score, required_score, + action = check_metric_action (task, metric_res->score, &required_score, metric_res->metric); if (action <= METRIC_ACTION_NOACTION) { task->worker->srv->stat->actions_stat[action]++; diff --git a/src/libserver/roll_history.c b/src/libserver/roll_history.c index d9553fa93..9a07fbad9 100644 --- a/src/libserver/roll_history.c +++ b/src/libserver/roll_history.c @@ -129,10 +129,8 @@ rspamd_roll_history_update (struct roll_history *history, } else { row->score = metric_res->score; - row->required_score = - metric_res->metric->actions[METRIC_ACTION_REJECT].score; - row->action = check_metric_action (metric_res->score, - metric_res->metric->actions[METRIC_ACTION_REJECT].score, + row->action = check_metric_action (task, metric_res->score, + &row->required_score, metric_res->metric); cbdata.pos = row->symbols; cbdata.remain = sizeof (row->symbols); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 3a000a3b3..c58aea556 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -1366,8 +1366,8 @@ lua_task_get_metric_action (lua_State *L) if (task && metric_name) { if ((metric_res = g_hash_table_lookup (task->results, metric_name)) != NULL) { - action = check_metric_action (metric_res->score, - metric_res->metric->actions[METRIC_ACTION_REJECT].score, + action = check_metric_action (task, metric_res->score, + NULL, metric_res->metric); lua_pushstring (L, str_action_metric (action)); } -- 2.39.5