aboutsummaryrefslogtreecommitdiffstats
path: root/src/controller.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-10-02 19:44:49 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-10-02 19:44:49 +0400
commit5d1f19fc9988261e23f190c216eb17958f178904 (patch)
tree5ce8f92a06147a887364d4d66f5ea3d8b77c988b /src/controller.c
parent80d2b194b1e8ce902a2feac5389bc4de8d5732a5 (diff)
downloadrspamd-5d1f19fc9988261e23f190c216eb17958f178904.tar.gz
rspamd-5d1f19fc9988261e23f190c216eb17958f178904.zip
* Add support for dynamic configuration to the controller's interface.
* File maps are now being watched even if they don't exist on rspamd start. Several fixes to dynamic configuration logic.
Diffstat (limited to 'src/controller.c')
-rw-r--r--src/controller.c127
1 files changed, 125 insertions, 2 deletions
diff --git a/src/controller.c b/src/controller.c
index dc3f84ec0..c987bc15f 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -37,6 +37,7 @@
#include "binlog.h"
#include "statfile_sync.h"
#include "lua/lua_common.h"
+#include "dynamic_cfg.h"
#define END "END" CRLF
@@ -72,7 +73,9 @@ enum command_type {
COMMAND_SYNC,
COMMAND_WEIGHTS,
COMMAND_GET,
- COMMAND_POST
+ COMMAND_POST,
+ COMMAND_ADD_SYMBOL,
+ COMMAND_ADD_ACTION
};
struct controller_command {
@@ -110,7 +113,9 @@ static struct controller_command commands[] = {
{"learn_spam", TRUE, COMMAND_LEARN_SPAM},
{"learn_ham", TRUE, COMMAND_LEARN_HAM},
{"get", FALSE, COMMAND_GET},
- {"post", FALSE, COMMAND_POST}
+ {"post", FALSE, COMMAND_POST},
+ {"add_symbol", TRUE, COMMAND_ADD_SYMBOL},
+ {"add_action", TRUE, COMMAND_ADD_ACTION}
};
static GList *custom_commands = NULL;
@@ -504,6 +509,114 @@ process_stat_command (struct controller_session *session)
}
static gboolean
+process_dynamic_conf_command (gchar **cmd_args, struct controller_session *session, gboolean is_action)
+{
+ struct config_file *cfg = session->cfg;
+ gchar *arg, *metric, *name, *err_str;
+ gdouble value;
+ gboolean res;
+
+ if (cfg->dynamic_conf == NULL) {
+ if (!session->restful) {
+ return rspamd_dispatcher_write (session->dispatcher, "dynamic config is not specified" CRLF, 0, FALSE, TRUE);
+ }
+ else {
+ return restful_write_reply (500, "dynamic config is not specified", NULL, 0, session->dispatcher);
+ }
+ }
+
+ if (session->restful) {
+ if ((arg = g_hash_table_lookup (session->kwargs, "metric")) == NULL) {
+ metric = DEFAULT_METRIC;
+ }
+ else {
+ metric = arg;
+ }
+ if ((arg = g_hash_table_lookup (session->kwargs, "name")) == NULL) {
+ goto invalid_arguments;
+ }
+ name = arg;
+ if ((arg = g_hash_table_lookup (session->kwargs, "value")) == NULL) {
+ goto invalid_arguments;
+ }
+ value = strtod (arg, &err_str);
+ if (err_str && *err_str != '\0') {
+ msg_info ("double value is invalid: %s", arg);
+ goto invalid_arguments;
+ }
+ }
+ else {
+ if (cmd_args[0] == NULL || cmd_args[1] == NULL) {
+ goto invalid_arguments;
+ }
+ if (cmd_args[2] == NULL) {
+ metric = DEFAULT_METRIC;
+ name = cmd_args[0];
+ arg = cmd_args[1];
+ value = strtod (arg, &err_str);
+ if (err_str && *err_str != '\0') {
+ msg_info ("double value is invalid: %s", arg);
+ goto invalid_arguments;
+ }
+ }
+ else {
+ metric = cmd_args[0];
+ name = cmd_args[1];
+ arg = cmd_args[2];
+ value = strtod (arg, &err_str);
+ if (err_str && *err_str != '\0') {
+ msg_info ("double value is invalid: %s", arg);
+ goto invalid_arguments;
+ }
+ }
+ }
+
+ if (is_action) {
+ res = add_dynamic_action (cfg, metric, name, value);
+ }
+ else {
+ res = add_dynamic_symbol (cfg, metric, name, value);
+ }
+
+ if (res) {
+
+ res = dump_dynamic_config (cfg);
+ if (res) {
+ if (!session->restful) {
+ return rspamd_dispatcher_write (session->dispatcher, "OK" CRLF, 0, FALSE, TRUE);
+ }
+ else {
+ return restful_write_reply (200, "OK", NULL, 0, session->dispatcher);
+ }
+ }
+ else {
+ if (!session->restful) {
+ return rspamd_dispatcher_write (session->dispatcher, "Error dumping dynamic config" CRLF, 0, FALSE, TRUE);
+ }
+ else {
+ return restful_write_reply (500, "Error dumping dynamic config", NULL, 0, session->dispatcher);
+ }
+ }
+ }
+ else {
+ if (!session->restful) {
+ return rspamd_dispatcher_write (session->dispatcher, "Cannot add dynamic rule" CRLF, 0, FALSE, TRUE);
+ }
+ else {
+ return restful_write_reply (500, "Cannot add dynamic rule", NULL, 0, session->dispatcher);
+ }
+ }
+
+invalid_arguments:
+ if (!session->restful) {
+ return rspamd_dispatcher_write (session->dispatcher, "Invalid arguments" CRLF, 0, FALSE, TRUE);
+ }
+ else {
+ return restful_write_reply (500, "Invalid arguments", NULL, 0, session->dispatcher);
+ }
+}
+
+static gboolean
process_command (struct controller_command *cmd, gchar **cmd_args, struct controller_session *session)
{
gchar out_buf[BUFSIZ], *arg, *err_str;
@@ -943,6 +1056,16 @@ process_command (struct controller_command *cmd, gchar **cmd_args, struct contro
case COMMAND_COUNTERS:
rspamd_hash_foreach (rspamd_main->counters, counter_write_callback, session);
break;
+ case COMMAND_ADD_ACTION:
+ if (check_auth (cmd, session)) {
+ return process_dynamic_conf_command (cmd_args, session, TRUE);
+ }
+ break;
+ case COMMAND_ADD_SYMBOL:
+ if (check_auth (cmd, session)) {
+ return process_dynamic_conf_command (cmd_args, session, FALSE);
+ }
+ break;
}
return TRUE;
}