]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Store headers order
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 3 Apr 2017 17:00:01 +0000 (18:00 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 3 Apr 2017 17:00:01 +0000 (18:00 +0100)
src/libmime/message.h
src/libmime/mime_headers.c
src/libmime/mime_headers.h
src/libmime/mime_parser.c
src/libserver/task.c
src/libserver/task.h

index 03e0e8345d038c402fbf11ebec823209549c9d12..22f4fd24dd4e90a9c3598a9f678198119ad20e76 100644 (file)
@@ -49,6 +49,7 @@ struct rspamd_mime_part {
        rspamd_ftok_t parsed_data;
        struct rspamd_mime_part *parent_part;
        GHashTable *raw_headers;
+       GQueue *headers_order;
        gchar *raw_headers_str;
        gsize raw_headers_len;
        enum rspamd_cte cte;
index 2ea4c0dcbc504291f0e519a4b23ad9745998d432..5044fc013a66e26041fcddce648c3c34bf5543c5 100644 (file)
@@ -121,7 +121,8 @@ rspamd_mime_header_check_special (struct rspamd_task *task,
 
 static void
 rspamd_mime_header_add (struct rspamd_task *task,
-               GHashTable *target, struct rspamd_mime_header *rh,
+               GHashTable *target, GQueue *order,
+               struct rspamd_mime_header *rh,
                gboolean check_special)
 {
        GPtrArray *ar;
@@ -137,6 +138,8 @@ rspamd_mime_header_add (struct rspamd_task *task,
                msg_debug_task ("add new raw header %s: %s", rh->name, rh->value);
        }
 
+       g_queue_push_tail (order, rh);
+
        if (check_special) {
                rspamd_mime_header_check_special (task, rh);
        }
@@ -145,7 +148,9 @@ rspamd_mime_header_add (struct rspamd_task *task,
 /* Convert raw headers to a list of struct raw_header * */
 void
 rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target,
-               const gchar *in, gsize len, gboolean check_newlines)
+               GQueue *order,
+               const gchar *in, gsize len,
+               gboolean check_newlines)
 {
        struct rspamd_mime_header *nh = NULL;
        const gchar *p, *c, *end;
@@ -153,7 +158,7 @@ rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target,
        gint state = 0, l, next_state = 100, err_state = 100, t_state;
        gboolean valid_folding = FALSE;
        guint nlines_count[RSPAMD_TASK_NEWLINES_MAX];
-       guint order = 0;
+       guint norder = 0;
 
        p = in;
        end = p + len;
@@ -334,16 +339,16 @@ rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target,
 
                        /* We also validate utf8 and replace all non-valid utf8 chars */
                        rspamd_mime_charset_utf_enforce (nh->decoded, strlen (nh->decoded));
-                       rspamd_mime_header_add (task, target, nh, check_newlines);
-                       nh->order = order ++;
+                       rspamd_mime_header_add (task, target, order, nh, check_newlines);
+                       nh->order = norder ++;
                        state = 0;
                        break;
                case 5:
                        /* Header has only name, no value */
                        nh->value = "";
                        nh->decoded = "";
-                       rspamd_mime_header_add (task, target, nh, check_newlines);
-                       nh->order = order ++;
+                       rspamd_mime_header_add (task, target, order, nh, check_newlines);
+                       nh->order = norder ++;
                        state = 0;
                        break;
                case 99:
index 9e77aa14b3ab71caf3618b2d4a2a5076c66f2a70..299e84dea279bafab34ab88dc35a13babb0d3e25 100644 (file)
@@ -47,7 +47,9 @@ struct rspamd_mime_header {
  * @param check_newlines
  */
 void rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target,
-               const gchar *in, gsize len, gboolean check_newlines);
+               GQueue *order,
+               const gchar *in, gsize len,
+               gboolean check_newlines);
 
 /**
  * Perform rfc2047 decoding of a header
index 1626cecbe547b5a2b2e19598b458000a371aef52..9b245e35a638b616ff1dd71c48fd8a9f2105e85b 100644 (file)
@@ -517,6 +517,7 @@ rspamd_mime_process_multipart_node (struct rspamd_task *task,
        npart->parent_part = multipart;
        npart->raw_headers =  g_hash_table_new_full (rspamd_strcase_hash,
                        rspamd_strcase_equal, NULL, rspamd_ptr_array_free_hard);
+       npart->headers_order = g_queue_new ();
        g_ptr_array_add (multipart->specific.mp.children, npart);
 
        if (hdr_pos > 0 && hdr_pos < str.len) {
@@ -527,6 +528,7 @@ rspamd_mime_process_multipart_node (struct rspamd_task *task,
 
                        if (task->raw_headers_content.len > 0) {
                                rspamd_mime_headers_process (task, npart->raw_headers,
+                                               npart->headers_order,
                                                npart->raw_headers_str,
                                                npart->raw_headers_len,
                                                FALSE);
@@ -1032,6 +1034,7 @@ rspamd_mime_parse_message (struct rspamd_task *task,
 
                        if (task->raw_headers_content.len > 0) {
                                rspamd_mime_headers_process (task, task->raw_headers,
+                                               task->headers_order,
                                                task->raw_headers_content.begin,
                                                task->raw_headers_content.len,
                                                TRUE);
@@ -1052,6 +1055,7 @@ rspamd_mime_parse_message (struct rspamd_task *task,
 
                                if (task->raw_headers_content.len > 0) {
                                        rspamd_mime_headers_process (task, task->raw_headers,
+                                                       task->headers_order,
                                                        task->raw_headers_content.begin,
                                                        task->raw_headers_content.len,
                                                        TRUE);
@@ -1078,6 +1082,7 @@ rspamd_mime_parse_message (struct rspamd_task *task,
                hdr_pos = rspamd_string_find_eoh (&str, &body_pos);
                npart->raw_headers =  g_hash_table_new_full (rspamd_strcase_hash,
                                rspamd_strcase_equal, NULL, rspamd_ptr_array_free_hard);
+               npart->headers_order = g_queue_new ();
 
                if (hdr_pos > 0 && hdr_pos < str.len) {
                        npart->raw_headers_str = str.str;
@@ -1086,6 +1091,7 @@ rspamd_mime_parse_message (struct rspamd_task *task,
 
                        if (npart->raw_headers_len > 0) {
                                rspamd_mime_headers_process (task, npart->raw_headers,
+                                               npart->headers_order,
                                                npart->raw_headers_str,
                                                npart->raw_headers_len,
                                                FALSE);
index cbd9a7a315298e144ab7be06fa1cfe9aba316d78..d2313afd78a4a92cd64230d005820adfd19f8316 100644 (file)
@@ -90,6 +90,7 @@ rspamd_task_new (struct rspamd_worker *worker, struct rspamd_config *cfg)
 
        new_task->raw_headers = g_hash_table_new_full (rspamd_strcase_hash,
                        rspamd_strcase_equal, NULL, rspamd_ptr_array_free_hard);
+       new_task->headers_order = g_queue_new ();
        new_task->request_headers = g_hash_table_new_full (rspamd_ftok_icase_hash,
                        rspamd_ftok_icase_equal, rspamd_fstring_mapped_ftok_free,
                        rspamd_request_header_dtor);
@@ -100,19 +101,22 @@ rspamd_task_new (struct rspamd_worker *worker, struct rspamd_config *cfg)
                        rspamd_ftok_icase_equal, rspamd_fstring_mapped_ftok_free,
                        rspamd_fstring_mapped_ftok_free);
        rspamd_mempool_add_destructor (new_task->task_pool,
-               (rspamd_mempool_destruct_t) g_hash_table_unref,
-               new_task->reply_headers);
+                       (rspamd_mempool_destruct_t) g_hash_table_unref,
+                       new_task->reply_headers);
        rspamd_mempool_add_destructor (new_task->task_pool,
-               (rspamd_mempool_destruct_t) g_hash_table_unref,
-               new_task->raw_headers);
+                       (rspamd_mempool_destruct_t) g_hash_table_unref,
+                       new_task->raw_headers);
+       rspamd_mempool_add_destructor (new_task->task_pool,
+                       (rspamd_mempool_destruct_t) g_queue_free,
+                       new_task->headers_order);
        new_task->emails = g_hash_table_new (rspamd_email_hash, rspamd_emails_cmp);
        rspamd_mempool_add_destructor (new_task->task_pool,
-               (rspamd_mempool_destruct_t) g_hash_table_unref,
-               new_task->emails);
+                       (rspamd_mempool_destruct_t) g_hash_table_unref,
+                       new_task->emails);
        new_task->urls = g_hash_table_new (rspamd_url_hash, rspamd_urls_cmp);
        rspamd_mempool_add_destructor (new_task->task_pool,
-               (rspamd_mempool_destruct_t) g_hash_table_unref,
-               new_task->urls);
+                       (rspamd_mempool_destruct_t) g_hash_table_unref,
+                       new_task->urls);
        new_task->parts = g_ptr_array_sized_new (4);
        rspamd_mempool_add_destructor (new_task->task_pool,
                        rspamd_ptr_array_free_hard, new_task->parts);
@@ -208,6 +212,8 @@ rspamd_task_free (struct rspamd_task *task)
                                g_hash_table_unref (p->raw_headers);
                        }
 
+                       g_queue_free (p->headers_order);
+
                        if (IS_CT_MULTIPART (p->ct)) {
                                if (p->specific.mp.children) {
                                        g_ptr_array_free (p->specific.mp.children, TRUE);
index db86a9ac98a99748cc650dcfb21e7201a45d45b3..e892e776f0ddab9f1e4661059518e67063e2b5bf 100644 (file)
@@ -157,6 +157,7 @@ struct rspamd_task {
        GHashTable *urls;                                                               /**< list of parsed urls                                                        */
        GHashTable *emails;                                                             /**< list of parsed emails                                                      */
        GHashTable *raw_headers;                                                /**< list of raw headers                                                        */
+       GQueue *headers_order;                                                  /**< order of raw headers                                                       */
        GHashTable *results;                                                    /**< hash table of metric_result indexed by
                                                                                                         *    metric's name                                                                     */
        GHashTable *lua_cache;                                                  /**< cache of lua objects                                                       */