]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Rework task errors and loading.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Jun 2015 12:02:27 +0000 (13:02 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Jun 2015 14:39:37 +0000 (15:39 +0100)
src/libserver/task.c
src/libserver/task.h

index 70da55afe2e37e079c02d7b4a790012f8c77a665..c632244157963f9bfd65b7590f0e2298847c68d9 100644 (file)
 #include "message.h"
 #include "lua/lua_common.h"
 
-static void
-gstring_destruct (gpointer ptr)
-{
-       GString *s = (GString *)ptr;
 
-       g_string_free (s, TRUE);
+static GQuark
+rspamd_task_quark (void)
+{
+       return g_quark_from_static_string ("task-error");
 }
 
 /*
@@ -72,12 +71,14 @@ rspamd_task_new (struct rspamd_worker *worker)
        new_task->raw_headers = g_hash_table_new (rspamd_strcase_hash,
                        rspamd_strcase_equal);
        new_task->request_headers = g_hash_table_new_full (rspamd_gstring_icase_hash,
-               rspamd_gstring_icase_equal, gstring_destruct, gstring_destruct);
+               rspamd_gstring_icase_equal, rspamd_gstring_free_hard,
+               rspamd_gstring_free_hard);
        rspamd_mempool_add_destructor (new_task->task_pool,
                (rspamd_mempool_destruct_t) g_hash_table_unref,
                new_task->request_headers);
        new_task->reply_headers = g_hash_table_new_full (rspamd_gstring_icase_hash,
-                       rspamd_gstring_icase_equal, gstring_destruct, gstring_destruct);
+                       rspamd_gstring_icase_equal, rspamd_gstring_free_hard,
+                       rspamd_gstring_free_hard);
        rspamd_mempool_add_destructor (new_task->task_pool,
                (rspamd_mempool_destruct_t) g_hash_table_unref,
                new_task->reply_headers);
@@ -253,6 +254,10 @@ rspamd_task_free (struct rspamd_task *task, gboolean is_soft)
                if (task->from_addr) {
                        rspamd_inet_address_destroy (task->from_addr);
                }
+               if (task->err) {
+                       g_error_free (task->err);
+               }
+
                rspamd_mempool_delete (task->task_pool);
                g_slice_free1 (sizeof (struct rspamd_task), task);
        }
@@ -274,20 +279,17 @@ rspamd_task_free_soft (gpointer ud)
        rspamd_task_free (task, FALSE);
 }
 
-
 gboolean
-rspamd_task_process (struct rspamd_task *task,
-       struct rspamd_http_message *msg, const gchar *start, gsize len,
-       gboolean process_extra_filters)
+rspamd_task_load_message (struct rspamd_task *task,
+       struct rspamd_http_message *msg, const gchar *start, gsize len)
 {
-       gint r;
        guint control_len;
        struct ucl_parser *parser;
        ucl_object_t *control_obj;
 
+       debug_task ("got input of length %z", task->msg.len);
        task->msg.start = start;
        task->msg.len = len;
-       debug_task ("got string of length %z", task->msg.len);
 
        if (msg) {
                rspamd_protocol_handle_headers (task, msg);
@@ -298,9 +300,8 @@ rspamd_task_process (struct rspamd_task *task,
                if (task->msg.len < task->message_len) {
                        msg_warn ("message has invalid message length: %ud and total len: %ud",
                                        task->message_len, task->msg.len);
-                       task->last_error = "Invalid length";
-                       task->error_code = RSPAMD_PROTOCOL_ERROR;
-                       task->state = WRITE_REPLY;
+                       g_set_error (&task->err, rspamd_task_quark(), RSPAMD_PROTOCOL_ERROR,
+                                       "Invalid length");
                        return FALSE;
                }
                control_len = task->msg.len - task->message_len;
@@ -325,14 +326,25 @@ rspamd_task_process (struct rspamd_task *task,
                }
        }
 
-       r = process_message (task);
-       if (r == -1) {
-               msg_warn ("processing of message failed");
-               task->last_error = "MIME processing error";
-               task->error_code = RSPAMD_FILTER_ERROR;
-               task->state = WRITE_REPLY;
-               return FALSE;
-       }
+       return TRUE;
+}
+
+gboolean
+rspamd_task_process (struct rspamd_task *task,
+       struct rspamd_http_message *msg, const gchar *start, gsize len,
+       guint stages)
+{
+       gint r;
+
+       if (stages & RSPAMD_TASK_STAGE_READ_MESSAGE) {
+               /* Process message itself */
+               r = process_message (task);
+               if (r == -1) {
+                       msg_warn ("processing of message failed");
+                       task->last_error = "MIME processing error";
+                       task->error_code = RSPAMD_FILTER_ERROR;
+                       return FALSE;
+               }
        if (!process_extra_filters) {
                task->flags |= RSPAMD_TASK_FLAG_SKIP_EXTRA;
        }
index 45e720eb8f5cb1129e9236fd8a573578b766922a..01a59b98cc5c75af97b0260830f13688b4800090 100644 (file)
@@ -62,6 +62,19 @@ enum rspamd_task_stage {
        RSPAMD_TASK_STAGE_WRITE_REPLY = (1 << 7)
 };
 
+#define RSPAMD_TASK_PROCESS_ALL (RSPAMD_TASK_STAGE_CONNECT | \
+               RSPAMD_TASK_STAGE_ENVELOPE | \
+               RSPAMD_TASK_STAGE_READ_MESSAGE | \
+               RSPAMD_TASK_STAGE_PRE_FILTERS | \
+               RSPAMD_TASK_STAGE_FILTERS | \
+               RSPAMD_TASK_STAGE_CLASSIFIERS | \
+               RSPAMD_TASK_STAGE_POST_FILTERS | \
+               RSPAMD_TASK_STAGE_WRITE_REPLY)
+#define RSPAMD_TASK_PROCESS_LEARN (RSPAMD_TASK_STAGE_CONNECT | \
+               RSPAMD_TASK_STAGE_ENVELOPE | \
+               RSPAMD_TASK_STAGE_READ_MESSAGE | \
+               RSPAMD_TASK_STAGE_WRITE_REPLY)
+
 #define RSPAMD_TASK_FLAG_MIME (1 << 0)
 #define RSPAMD_TASK_FLAG_JSON (1 << 1)
 #define RSPAMD_TASK_FLAG_SKIP_EXTRA (1 << 2)
@@ -138,8 +151,7 @@ struct rspamd_task {
        GList *messages;                                            /**< list of messages that would be reported                */
        GHashTable *re_cache;                                       /**< cache for matched or not matched regexps               */
        struct rspamd_config *cfg;                                  /**< pointer to config object                                               */
-       gchar *last_error;                                          /**< last error                                                                             */
-       gint error_code;                                                /**< code of last error                                                         */
+       GError *err;
        rspamd_mempool_t *task_pool;                                    /**< memory pool for task                                                       */
        double time_real;
        double time_virtual;
@@ -187,15 +199,22 @@ void rspamd_task_restore (void *arg);
 gboolean rspamd_task_fin (void *arg);
 
 /**
- * Process task from http message and write reply or call task->fin_handler
+ * Load HTTP message with body in `msg` to an rspamd_task
+ * @param task
+ * @param msg
+ * @param start
+ * @param len
+ * @return
+ */
+gboolean rspamd_task_load_message (struct rspamd_task *task,
+       struct rspamd_http_message *msg, const gchar *start, gsize len);
+
+/**
+ * Process task
  * @param task task to process
- * @param msg incoming http message
- * @param process_extra_filters whether to check pre and post filters
  * @return task has been successfully parsed and processed
  */
-gboolean rspamd_task_process (struct rspamd_task *task,
-       struct rspamd_http_message *msg, const gchar *start, gsize len,
-       gboolean process_extra_filters);
+gboolean rspamd_task_process (struct rspamd_task *task, guint stages);
 
 /**
  * Return address of sender or NULL