From 7cdfdccdd8fb845d30d9e0d3dacff36de76e4114 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 30 Mar 2015 16:20:00 +0100 Subject: [PATCH] Add control section parsing. --- src/libserver/protocol.c | 106 +++++++++++++++++++++++++++++++++++++++ src/libserver/protocol.h | 9 ++++ src/libserver/task.c | 2 + 3 files changed, 117 insertions(+) diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 1f5b1f447..4dab60171 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -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) diff --git a/src/libserver/protocol.h b/src/libserver/protocol.h index 8fdd7e56f..c3a73abec 100644 --- a/src/libserver/protocol.h +++ b/src/libserver/protocol.h @@ -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 diff --git a/src/libserver/task.c b/src/libserver/task.c index 4c8934ada..0dd77a1e5 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -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; -- 2.39.5