@@ -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 |
@@ -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 |
@@ -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]++; |
@@ -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); |
@@ -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)); | |||
} |