]> source.dussan.org Git - rspamd.git/commitdiff
Add support of spamc compatible output.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Mar 2015 15:19:15 +0000 (15:19 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Mar 2015 15:19:15 +0000 (15:19 +0000)
src/libserver/protocol.c
src/libserver/task.h

index 599d6e4ce6e2e4f5478567e42891b84534f1f67e..3a35efba352ddad7603e361f893aea3ed658500e 100644 (file)
@@ -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;
index 135e8bf9269ad9bc6d451463f344cd1bcff13a79..917ef8bccc8b53a29def26822a79463fb2d3e1ac 100644 (file)
@@ -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                                                      */