From: Vsevolod Stakhov Date: Wed, 11 Mar 2015 15:19:15 +0000 (+0000) Subject: Add support of spamc compatible output. X-Git-Tag: 0.9.0~521 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=82870c1b5aaa92a3fe0ce0c6ac5d5da8165f4a85;p=thirdparty%2Frspamd.git Add support of spamc compatible output. --- diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 599d6e4ce6..3a35efba35 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -429,6 +429,10 @@ rspamd_protocol_handle_request (struct rspamd_task *task, ret = rspamd_protocol_handle_url (task, msg); } + if (msg->flags & RSPAMD_HTTP_FLAG_SPAMC) { + task->is_spamc = TRUE; + } + return ret; } @@ -728,7 +732,7 @@ rspamd_metric_result_ucl (struct rspamd_task *task, } static void -rspamd_ucl_tolegacy_output (struct rspamd_task *task, +rspamd_ucl_torspamc_output (struct rspamd_task *task, ucl_object_t *top, GString *out) { @@ -786,6 +790,40 @@ rspamd_ucl_tolegacy_output (struct rspamd_task *task, g_string_append_printf (out, "Message-ID: %s\r\n", task->message_id); } +static void +rspamd_ucl_tospamc_output (struct rspamd_task *task, + ucl_object_t *top, + GString *out) +{ + const ucl_object_t *metric, *score, + *required_score, *is_spam, *elt; + ucl_object_iter_t iter = NULL; + + metric = ucl_object_find_key (top, DEFAULT_METRIC); + if (metric != NULL) { + score = ucl_object_find_key (metric, "score"); + required_score = ucl_object_find_key (metric, "required_score"); + is_spam = ucl_object_find_key (metric, "is_spam"); + g_string_append_printf (out, + "Spam: %s ; %.2f / %.2f\r\n\r\n", + ucl_object_toboolean (is_spam) ? "True" : "False", + ucl_object_todouble (score), + ucl_object_todouble (required_score)); + + while ((elt = ucl_iterate_object (metric, &iter, true)) != NULL) { + if (elt->type == UCL_OBJECT) { + g_string_append_printf (out, "%s,", + ucl_object_key (elt)); + } + } + /* Ugly hack, but the whole spamc is ugly */ + if (out->str[out->len - 1] == ',') { + g_string_truncate (out, out->len - 1); + g_string_append (out, CRLF); + } + } +} + void rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task *task) @@ -855,11 +893,16 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, msg->body = g_string_sized_new (BUFSIZ); - if (msg->method < HTTP_SYMBOLS) { + if (msg->method < HTTP_SYMBOLS && !task->is_spamc) { rspamd_ucl_emit_gstring (top, UCL_EMIT_JSON_COMPACT, msg->body); } else { - rspamd_ucl_tolegacy_output (task, top, msg->body); + if (task->is_spamc) { + rspamd_ucl_tospamc_output (task, top, msg->body); + } + else { + rspamd_ucl_torspamc_output (task, top, msg->body); + } } ucl_object_unref (top); @@ -893,6 +936,10 @@ rspamd_protocol_write_reply (struct rspamd_task *task) /* Turn compatibility on */ msg->method = HTTP_SYMBOLS; } + if (task->is_spamc) { + msg->flags |= RSPAMD_HTTP_FLAG_SPAMC; + } + msg->date = time (NULL); task->state = WRITING_REPLY; diff --git a/src/libserver/task.h b/src/libserver/task.h index 135e8bf926..917ef8bccc 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -75,11 +75,13 @@ struct rspamd_task { enum rspamd_command cmd; /**< command */ struct custom_command *custom_cmd; /**< custom command if any */ gint sock; /**< socket descriptor */ + /* TODO: all these fields should be converted to flags */ gboolean is_mime; /**< if this task is mime task */ gboolean is_json; /**< output is JSON */ gboolean skip_extra_filters; /**< skip pre and post filters */ gboolean is_skipped; /**< whether message was skipped by configuration */ gboolean extended_urls; /**< output URLs in details */ + gboolean is_spamc; /**< need legacy spamc output */ gchar *helo; /**< helo header value */ gchar *queue_id; /**< queue id if specified */