From: Vsevolod Stakhov Date: Wed, 11 Mar 2015 15:19:15 +0000 (+0000) Subject: Add support of spamc compatible output. X-Git-Tag: 0.8.3~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a4266eca4e65c88df5731d746f7076e6da9bd77b;p=thirdparty%2Frspamd.git Add support of spamc compatible output. --- diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index f527ed6fc3..6e11eb27a7 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -450,6 +450,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; } @@ -749,7 +753,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) { @@ -805,6 +809,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) @@ -874,11 +912,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); @@ -907,6 +950,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 1261dd1345..ebdcd28da0 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 */