aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libmime/filter.c27
-rw-r--r--src/libserver/protocol.c30
-rw-r--r--src/libserver/task.c145
-rw-r--r--src/libserver/task.h4
4 files changed, 73 insertions, 133 deletions
diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index a9089818c..83dc24dc3 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -297,33 +297,6 @@ rspamd_task_insert_result_single (struct rspamd_task *task,
insert_result_common (task, symbol, flag, opts, TRUE);
}
-static gboolean
-check_metric_settings (struct rspamd_task *task, struct metric *metric,
- double *score)
-{
- const ucl_object_t *mobj, *reject, *act;
- double val;
-
- if (task->settings == NULL) {
- return FALSE;
- }
-
- mobj = ucl_object_find_key (task->settings, metric->name);
- if (mobj != NULL) {
- act = ucl_object_find_key (mobj, "actions");
- if (act != NULL) {
- reject = ucl_object_find_key (act,
- rspamd_action_to_str (METRIC_ACTION_REJECT));
- if (reject != NULL && ucl_object_todouble_safe (reject, &val)) {
- *score = val;
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
static void
insert_metric_header (gpointer metric_name, gpointer metric_value,
gpointer data)
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index f49535f37..acdf1129a 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -101,6 +101,12 @@
static GList *custom_commands = NULL;
+static GQuark
+rspamd_protocol_quark (void)
+{
+ return g_quark_from_static_string ("protocol-error");
+}
+
/*
* Remove <> from the fixed string and copy it to the pool
*/
@@ -146,8 +152,7 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
const gchar *p;
if (msg->url == NULL || msg->url->len == 0) {
- task->last_error = "command is absent";
- task->error_code = 400;
+ g_set_error (&task->err, rspamd_protocol_quark(), 400, "missing command");
return FALSE;
}
@@ -229,9 +234,9 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
return TRUE;
err:
- debug_task ("bad command: %s", p);
- task->last_error = "invalid command";
- task->error_code = 400;
+ g_set_error (&task->err, rspamd_protocol_quark(), 400, "invalid command: %s",
+ p);
+
return FALSE;
}
@@ -433,8 +438,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
if (!res && task->cfg->strict_protocol_headers) {
msg_err (
"deny processing of a request with incorrect or unknown headers");
- task->last_error = "invalid header";
- task->error_code = 400;
+ g_set_error (&task->err, rspamd_protocol_quark, 400, "invalid header command");
return FALSE;
}
@@ -1103,17 +1107,19 @@ rspamd_protocol_write_reply (struct rspamd_task *task)
msg->date = time (NULL);
- task->state = WRITING_REPLY;
debug_task ("writing reply to client");
- if (task->error_code != 0) {
+ if (task->err != NULL) {
ucl_object_t *top = NULL;
top = ucl_object_typed_new (UCL_OBJECT);
- msg->code = 500 + task->error_code % 100;
- msg->status = g_string_new (task->last_error);
- ucl_object_insert_key (top, ucl_object_fromstring (task->last_error),
+ msg->code = 500 + task->err->code % 100;
+ msg->status = g_string_new (task->err->message);
+ ucl_object_insert_key (top, ucl_object_fromstring (task->err->message),
"error", 0, false);
+ ucl_object_insert_key (top,
+ ucl_object_fromstring (g_quark_to_string (task->err->domain)),
+ "error_domain", 0, false);
msg->body = g_string_sized_new (256);
rspamd_ucl_emit_gstring (top, UCL_EMIT_JSON_COMPACT, msg->body);
ucl_object_unref (top);
diff --git a/src/libserver/task.c b/src/libserver/task.c
index 33a03049f..c7803cabd 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -27,7 +27,8 @@
#include "protocol.h"
#include "message.h"
#include "lua/lua_common.h"
-
+#include "composites.h"
+#include "stat_api.h"
static GQuark
rspamd_task_quark (void)
@@ -122,64 +123,20 @@ gboolean
rspamd_task_fin (void *arg)
{
struct rspamd_task *task = (struct rspamd_task *) arg;
- gint r;
/* Task is already finished or skipped */
- if (task->state == WRITE_REPLY) {
+ if (RSPAMD_TASK_IS_PROCESSED (task)) {
rspamd_task_reply (task);
return TRUE;
}
- /* We processed all filters and want to process statfiles */
- if (task->state != WAIT_POST_FILTER && task->state != WAIT_PRE_FILTER) {
- /* Process all statfiles */
- /* Non-threaded version */
- rspamd_process_statistics (task);
-
- if (task->cfg->post_filters) {
- /* More to process */
- /* Special state */
- task->state = WAIT_POST_FILTER;
- return FALSE;
- }
-
- }
-
- /* We are on post-filter waiting state */
- if (task->state != WAIT_PRE_FILTER) {
- /* Check if we have all events finished */
- task->state = WRITE_REPLY;
+ if (!rspamd_task_process (task, RSPAMD_TASK_PROCESS_ALL)) {
rspamd_task_reply (task);
- }
- else {
- /* We were waiting for pre-filter */
- if (task->pre_result.action != METRIC_ACTION_NOACTION) {
- /* Write result based on pre filters */
- task->state = WRITE_REPLY;
- rspamd_task_reply (task);
- return TRUE;
- }
- else {
- task->state = WAIT_FILTER;
- r = rspamd_process_filters (task);
- if (r == -1) {
- task->last_error = "Filter processing error";
- task->error_code = RSPAMD_FILTER_ERROR;
- task->state = WRITE_REPLY;
- rspamd_task_reply (task);
- return TRUE;
- }
-
- if (RSPAMD_TASK_IS_SKIPPED (task)) {
- rspamd_task_reply (task);
- }
- else {
- return FALSE;
- }
- }
+ return TRUE;
}
- return TRUE;
+ /* One more iteration */
+ return FALSE;
}
/*
@@ -188,13 +145,7 @@ rspamd_task_fin (void *arg)
void
rspamd_task_restore (void *arg)
{
- struct rspamd_task *task = (struct rspamd_task *) arg;
-
- /* Call post filters */
- if (task->state == WAIT_POST_FILTER &&
- !(task->flags & RSPAMD_TASK_FLAG_SKIP_EXTRA)) {
- rspamd_lua_call_post_filters (task);
- }
+ /* XXX: not needed now ? */
}
/*
@@ -357,6 +308,51 @@ rspamd_task_select_processing_stage (struct rspamd_task *task, guint stages)
}
static gboolean
+check_metric_settings (struct rspamd_task *task, struct metric *metric,
+ double *score)
+{
+ const ucl_object_t *mobj, *reject, *act;
+ double val;
+
+ if (task->settings == NULL) {
+ return FALSE;
+ }
+
+ mobj = ucl_object_find_key (task->settings, metric->name);
+ if (mobj != NULL) {
+ act = ucl_object_find_key (mobj, "actions");
+ if (act != NULL) {
+ reject = ucl_object_find_key (act,
+ rspamd_action_to_str (METRIC_ACTION_REJECT));
+ if (reject != NULL && ucl_object_todouble_safe (reject, &val)) {
+ *score = val;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/* Return true if metric has score that is more than spam score for it */
+static gboolean
+check_metric_is_spam (struct rspamd_task *task, struct metric *metric)
+{
+ struct metric_result *res;
+ double ms;
+
+ res = g_hash_table_lookup (task->results, metric->name);
+ if (res) {
+ if (!check_metric_settings (task, metric, &ms)) {
+ ms = metric->actions[METRIC_ACTION_REJECT].score;
+ }
+ return (ms > 0 && res->score >= ms);
+ }
+
+ return FALSE;
+}
+
+static gboolean
rspamd_process_filters (struct rspamd_task *task)
{
GList *cur;
@@ -607,38 +603,3 @@ rspamd_learn_task_spam (struct rspamd_classifier_config *cl,
{
return rspamd_stat_learn (task, is_spam, task->cfg->lua_state, err);
}
-
-/* Return true if metric has score that is more than spam score for it */
-static gboolean
-check_metric_is_spam (struct rspamd_task *task, struct metric *metric)
-{
- struct metric_result *res;
- double ms;
-
- /* Avoid concurrency while checking results */
-#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
- g_static_mutex_lock (&result_mtx);
-#else
- G_LOCK (result_mtx);
-#endif
- res = g_hash_table_lookup (task->results, metric->name);
- if (res) {
-#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
- g_static_mutex_unlock (&result_mtx);
-#else
- G_UNLOCK (result_mtx);
-#endif
- if (!check_metric_settings (task, metric, &ms)) {
- ms = metric->actions[METRIC_ACTION_REJECT].score;
- }
- return (ms > 0 && res->score >= ms);
- }
-
-#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
- g_static_mutex_unlock (&result_mtx);
-#else
- G_UNLOCK (result_mtx);
-#endif
-
- return FALSE;
-}
diff --git a/src/libserver/task.h b/src/libserver/task.h
index d7698a130..3a1d11458 100644
--- a/src/libserver/task.h
+++ b/src/libserver/task.h
@@ -70,11 +70,11 @@ enum rspamd_task_stage {
RSPAMD_TASK_STAGE_FILTERS | \
RSPAMD_TASK_STAGE_CLASSIFIERS | \
RSPAMD_TASK_STAGE_POST_FILTERS | \
- RSPAMD_TASK_STAGE_WRITE_REPLY)
+ RSPAMD_TASK_STAGE_DONE)
#define RSPAMD_TASK_PROCESS_LEARN (RSPAMD_TASK_STAGE_CONNECT | \
RSPAMD_TASK_STAGE_ENVELOPE | \
RSPAMD_TASK_STAGE_READ_MESSAGE | \
- RSPAMD_TASK_STAGE_WRITE_REPLY)
+ RSPAMD_TASK_STAGE_DONE)
#define RSPAMD_TASK_FLAG_MIME (1 << 0)
#define RSPAMD_TASK_FLAG_JSON (1 << 1)