]> source.dussan.org Git - rspamd.git/commitdiff
Add control section parsing.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 30 Mar 2015 15:20:00 +0000 (16:20 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 30 Mar 2015 15:20:00 +0000 (16:20 +0100)
src/libserver/protocol.c
src/libserver/protocol.h
src/libserver/task.c

index 1f5b1f4470856039ff07e985393e6b00d0839cfa..4dab6017104f3e9d6bb1b1fa5891f393b7de4fb3 100644 (file)
@@ -26,6 +26,7 @@
 #include "main.h"
 #include "util.h"
 #include "cfg_file.h"
+#include "cfg_rcl.h"
 #include "message.h"
 #include "utlist.h"
 
@@ -439,6 +440,111 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
        return TRUE;
 }
 
+#define BOOL_TO_FLAG(val, flags, flag) do {                                                                    \
+       if ((val)) (flags) |= (flag);                                                                                   \
+       else (flags) &= ~(flag);                                                                                                \
+} while(0)
+
+gboolean
+rspamd_protocol_parse_task_flags (rspamd_mempool_t *pool,
+       const ucl_object_t *obj,
+       gpointer ud,
+       struct rspamd_rcl_section *section,
+       GError **err)
+{
+       struct rspamd_rcl_struct_parser *pd = ud;
+       gint *target;
+       const gchar *key;
+       gboolean value;
+
+       target = (gint *)(((gchar *)pd->user_struct) + pd->offset);
+       key = ucl_object_key (obj);
+       value = ucl_object_toboolean (obj);
+
+       if (key != NULL) {
+               if (g_ascii_strcasecmp (key, "pass_all") == 0) {
+                       BOOL_TO_FLAG (value, *target, RSPAMD_TASK_FLAG_PASS_ALL);
+               }
+               else if (g_ascii_strcasecmp (key, "no_log") == 0) {
+                       BOOL_TO_FLAG (value, *target, RSPAMD_TASK_FLAG_NO_LOG);
+               }
+       }
+
+       return TRUE;
+}
+
+static struct rspamd_rcl_section *control_parser = NULL;
+
+static void
+rspamd_protocol_control_parser_init (void)
+{
+       struct rspamd_rcl_section *sub;
+
+       if (control_parser == NULL) {
+               sub = rspamd_rcl_add_section (&control_parser,
+                               "*",
+                               NULL,
+                               UCL_OBJECT,
+                               FALSE,
+                               TRUE);
+               /* Default handlers */
+               rspamd_rcl_add_default_handler (sub,
+                               "ip",
+                               rspamd_rcl_parse_struct_addr,
+                               G_STRUCT_OFFSET (struct rspamd_task, from_addr),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "from",
+                               rspamd_rcl_parse_struct_mime_addr,
+                               G_STRUCT_OFFSET (struct rspamd_task, from_envelope),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "rcpt",
+                               rspamd_rcl_parse_struct_mime_addr,
+                               G_STRUCT_OFFSET (struct rspamd_task, rcpt_envelope),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "helo",
+                               rspamd_rcl_parse_struct_string,
+                               G_STRUCT_OFFSET (struct rspamd_task, helo),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "user",
+                               rspamd_rcl_parse_struct_string,
+                               G_STRUCT_OFFSET (struct rspamd_task, user),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "pass_all",
+                               rspamd_protocol_parse_task_flags,
+                               G_STRUCT_OFFSET (struct rspamd_task, flags),
+                               0);
+               rspamd_rcl_add_default_handler (sub,
+                               "json",
+                               rspamd_protocol_parse_task_flags,
+                               G_STRUCT_OFFSET (struct rspamd_task, flags),
+                               0);
+       }
+}
+
+gboolean
+rspamd_protocol_handle_control (struct rspamd_task *task,
+               const ucl_object_t *control)
+{
+       GError *err = NULL;
+
+       rspamd_protocol_control_parser_init ();
+
+       if (!rspamd_rcl_parse (control_parser, task, task->task_pool,
+                       control, &err)) {
+               msg_warn ("cannot parse control block: %e", err);
+               g_error_free (err);
+
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 gboolean
 rspamd_protocol_handle_request (struct rspamd_task *task,
        struct rspamd_http_message *msg)
index 8fdd7e56f59a1bc669d214234ef6fee90b8af759..c3a73abec9308aaa8e05a8debee827a4db02c709 100644 (file)
@@ -29,6 +29,15 @@ struct metric;
 gboolean rspamd_protocol_handle_headers (struct rspamd_task *task,
        struct rspamd_http_message *msg);
 
+/**
+ * Process control chunk and update task structure accordingly
+ * @param task
+ * @param control
+ * @return
+ */
+gboolean rspamd_protocol_handle_control (struct rspamd_task *task,
+               const ucl_object_t *control);
+
 /**
  * Process HTTP request to the task structure
  * @param task
index 4c8934ada82cfe2eb9a7871c1830ca44c2abd693..0dd77a1e5f24891004edef9c653e70a2e8f1e7cb 100644 (file)
@@ -346,6 +346,8 @@ rspamd_task_process (struct rspamd_task *task,
                        else {
                                control_obj = ucl_parser_get_object (parser);
                                ucl_parser_free (parser);
+                               rspamd_protocol_handle_control (task, control_obj);
+                               ucl_object_unref (control_obj);
                        }
 
                        task->msg.start += control_len;