diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-02-28 16:09:05 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-02-28 16:09:05 +0000 |
commit | 822a30cc3aa86706b556face0b2c1b87f444d18d (patch) | |
tree | f4134d29eeae066e96afa93b1048bcaa0471d00d | |
parent | 2f97a5cc06027be61ac7a4ac9a02939de855ae3e (diff) | |
download | rspamd-822a30cc3aa86706b556face0b2c1b87f444d18d.tar.gz rspamd-822a30cc3aa86706b556face0b2c1b87f444d18d.zip |
Implement learn spam and learn ham.
-rw-r--r-- | src/webui.c | 169 |
1 files changed, 99 insertions, 70 deletions
diff --git a/src/webui.c b/src/webui.c index a6af7728f..1043fadbe 100644 --- a/src/webui.c +++ b/src/webui.c @@ -115,6 +115,7 @@ struct rspamd_webui_session { struct rspamd_webui_worker_ctx *ctx; memory_pool_t *pool; struct worker_task *task; + struct classifier_config *cl; struct { union { struct in_addr in4; @@ -123,6 +124,7 @@ struct rspamd_webui_session { gboolean ipv6; gboolean has_addr; } from_addr; + gboolean is_spam; }; static sig_atomic_t wanna_die = 0; @@ -209,6 +211,21 @@ rspamd_webui_send_error (struct rspamd_http_connection_entry *entry, gint code, } static void +rspamd_webui_send_string (struct rspamd_http_connection_entry *entry, const gchar *str) +{ + struct rspamd_http_message *msg; + + msg = rspamd_http_new_message (HTTP_RESPONSE); + msg->date = time (NULL); + msg->code = 200; + msg->body = g_string_new (str); + rspamd_http_connection_reset (entry->conn); + rspamd_http_connection_write_message (entry->conn, msg, NULL, + "application/json", entry, entry->conn->fd, entry->rt->ptv, entry->rt->ev_base); + entry->is_reply = TRUE; +} + +static void rspamd_webui_send_ucl (struct rspamd_http_connection_entry *entry, ucl_object_t *obj) { struct rspamd_http_message *msg; @@ -1199,11 +1216,38 @@ rspamd_webui_handle_history (struct rspamd_http_connection_entry *conn_ent, return 0; } +static gboolean +rspamd_webui_learn_fin_task (void *ud) +{ + struct worker_task *task = ud; + struct rspamd_webui_session *session; + struct rspamd_http_connection_entry *conn_ent; + GError *err = NULL; + + conn_ent = task->fin_arg; + session = conn_ent->ud; + + if (!learn_task_spam (session->cl, task, session->is_spam, &err)) { + rspamd_webui_send_error (conn_ent, 500 + err->code, err->message); + return TRUE; + } + /* Successful learn */ + rspamd_webui_send_string (conn_ent, "{\"success\":true}"); + + return TRUE; +} + static int -rspamd_webui_handle_learnspam (struct rspamd_http_connection_entry *conn_ent, - struct rspamd_http_message *msg) +rspamd_webui_handle_learn_common (struct rspamd_http_connection_entry *conn_ent, + struct rspamd_http_message *msg, gboolean is_spam) { struct rspamd_webui_session *session = conn_ent->ud; + struct rspamd_webui_worker_ctx *ctx; + struct classifier_config *cl; + struct worker_task *task; + const gchar *classifier; + + ctx = session->ctx; if (!rspamd_webui_check_password (conn_ent, session->ctx, msg)) { return 0; @@ -1215,12 +1259,49 @@ rspamd_webui_handle_learnspam (struct rspamd_http_connection_entry *conn_ent, return 0; } - session->task = construct_task (session->ctx->worker); - session->task->ev_base = session->ctx->ev_base; + if ((classifier = rspamd_http_message_find_header (msg, "Classifier")) == NULL) { + classifier = "bayes"; + } + + cl = find_classifier_conf (ctx->cfg, classifier); + if (cl == NULL) { + rspamd_webui_send_error (conn_ent, 400, "Classifier not found"); + return 0; + } + + task = construct_task (session->ctx->worker); + task->ev_base = session->ctx->ev_base; + task->msg = msg->body; + + task->resolver = ctx->resolver; + task->ev_base = ctx->ev_base; + + task->s = new_async_session (session->pool, rspamd_webui_learn_fin_task, NULL, + free_task_hard, task); + task->s->wanna_die = TRUE; + task->fin_arg = conn_ent; + + if (process_message (task) == -1) { + msg_warn ("processing of message failed"); + destroy_session (task->s); + rspamd_webui_send_error (conn_ent, 500, "Message cannot be processed"); + return 0; + } + + if (process_filters (task) == -1) { + msg_warn ("filters cannot be processed for %s", task->message_id); + destroy_session (task->s); + rspamd_webui_send_error (conn_ent, 500, "Filters cannot be processed"); + return 0; + } + + session->task = task; + session->cl = cl; + session->is_spam = is_spam; return 0; } -#if 0 + /* * Learn spam command handler: * request: /learnspam @@ -1228,40 +1309,12 @@ rspamd_webui_handle_learnspam (struct rspamd_http_connection_entry *conn_ent, * input: plaintext data * reply: json {"success":true} or {"error":"error message"} */ -static void -rspamd_webui_handle_learn_spam (struct evhttp_request *req, gpointer arg) +static int +rspamd_webui_handle_learnspam (struct rspamd_http_connection_entry *conn_ent, + struct rspamd_http_message *msg) { - struct rspamd_webui_worker_ctx *ctx = arg; - struct evbuffer *evb, *inb; - GError *err = NULL; - struct learn_callback_data *cbdata; - - if (!http_check_password (ctx, req)) { - return; - } - - inb = req->input_buffer; - - cbdata = http_prepare_learn (req, ctx, inb, TRUE, &err); - if (cbdata == NULL) { - /* Handle error */ - evb = evbuffer_new (); - if (!evb) { - msg_err ("cannot allocate evbuffer for reply"); - evhttp_send_reply (req, HTTP_INTERNAL, "500 insufficient memory", NULL); - return; - } - evbuffer_add_printf (evb, "{\"error\":\"%s\"}" CRLF, err->message); - evhttp_add_header (req->output_headers, "Connection", "close"); - http_calculate_content_length (evb, req); - - evhttp_send_reply (req, err->code, err->message, evb); - evbuffer_free (evb); - g_error_free (err); - return; - } + return rspamd_webui_handle_learn_common (conn_ent, msg, TRUE); } - /* * Learn ham command handler: * request: /learnham @@ -1269,40 +1322,13 @@ rspamd_webui_handle_learn_spam (struct evhttp_request *req, gpointer arg) * input: plaintext data * reply: json {"success":true} or {"error":"error message"} */ -static void -rspamd_webui_handle_learn_ham (struct evhttp_request *req, gpointer arg) +static int +rspamd_webui_handle_learnham (struct rspamd_http_connection_entry *conn_ent, + struct rspamd_http_message *msg) { - struct rspamd_webui_worker_ctx *ctx = arg; - struct evbuffer *evb, *inb; - GError *err = NULL; - struct learn_callback_data *cbdata; - - if (!http_check_password (ctx, req)) { - return; - } - - inb = req->input_buffer; - - cbdata = http_prepare_learn (req, ctx, inb, FALSE, &err); - if (cbdata == NULL) { - /* Handle error */ - evb = evbuffer_new (); - if (!evb) { - msg_err ("cannot allocate evbuffer for reply"); - evhttp_send_reply (req, HTTP_INTERNAL, "500 insufficient memory", NULL); - return; - } - evbuffer_add_printf (evb, "{\"error\":\"%s\"}" CRLF, err->message); - evhttp_add_header (req->output_headers, "Connection", "close"); - http_calculate_content_length (evb, req); - - evhttp_send_reply (req, err->code, err->message, evb); - evbuffer_free (evb); - g_error_free (err); - return; - } + return rspamd_webui_handle_learn_common (conn_ent, msg, TRUE); } - +#if 0 /* * Save actions command handler: * request: /saveactions @@ -1660,6 +1686,9 @@ rspamd_webui_finish_handler (struct rspamd_http_connection_entry *conn_ent) if (session->pool) { memory_pool_delete (session->pool); } + if (session->task != NULL) { + destroy_session (session->task->s); + } g_slice_free1 (sizeof (struct rspamd_webui_session), session); } @@ -1787,9 +1816,9 @@ start_webui_worker (struct rspamd_worker *worker) rspamd_http_router_add_path (ctx->http, PATH_PIE_CHART, rspamd_webui_handle_pie_chart); rspamd_http_router_add_path (ctx->http, PATH_HISTORY, rspamd_webui_handle_history); rspamd_http_router_add_path (ctx->http, PATH_LEARN_SPAM, rspamd_webui_handle_learnspam); + rspamd_http_router_add_path (ctx->http, PATH_LEARN_HAM, rspamd_webui_handle_learnham); #if 0 rspamd_http_router_add_path (ctx->http, PATH_GRAPH, rspamd_webui_handle_graph, ctx); - rspamd_http_router_add_path (ctx->http, PATH_LEARN_HAM, rspamd_webui_handle_learn_ham, ctx); rspamd_http_router_add_path (ctx->http, PATH_SAVE_ACTIONS, rspamd_webui_handle_save_actions, ctx); rspamd_http_router_add_path (ctx->http, PATH_SAVE_SYMBOLS, rspamd_webui_handle_save_symbols, ctx); rspamd_http_router_add_path (ctx->http, PATH_SAVE_MAP, rspamd_webui_handle_save_map, ctx); |