Browse Source

* Add symbols command for webui.

tags/0.5.4
Vsevolod Stakhov 11 years ago
parent
commit
54c2f784b7
4 changed files with 166 additions and 10 deletions
  1. 18
    0
      src/cfg_file.h
  2. 16
    0
      src/cfg_utils.c
  3. 45
    6
      src/cfg_xml.c
  4. 87
    4
      src/webui.c

+ 18
- 0
src/cfg_file.h View File

@@ -138,6 +138,23 @@ struct module_opt {
enum lua_var_type lua_type; /**< type of lua variable */
};

/**
* Symbol definition
*/
struct symbol_def {
gchar *name;
gchar *description;
gdouble weight;
};

/**
* Symbols group
*/
struct symbols_group {
gchar *name;
GList *symbols;
};

/**
* Statfile section definition
*/
@@ -308,6 +325,7 @@ struct config_file {
GHashTable* modules_opts; /**< hash for module options indexed by module name */
GHashTable* variables; /**< hash of $variables defined in config, indexed by variable name */
GHashTable* metrics; /**< hash of metrics indexed by metric name */
GList* symbols_groups; /**< groups of symbols */
GList* metrics_list; /**< linked list of metrics */
GHashTable* metrics_symbols; /**< hash table of metrics indexed by symbol */
GHashTable* c_modules; /**< hash of c modules indexed by module name */

+ 16
- 0
src/cfg_utils.c View File

@@ -236,6 +236,9 @@ init_defaults (struct config_file *cfg)
void
free_config (struct config_file *cfg)
{
GList *cur;
struct symbols_group *gr;

remove_all_maps (cfg);
g_hash_table_remove_all (cfg->modules_opts);
g_hash_table_unref (cfg->modules_opts);
@@ -251,6 +254,19 @@ free_config (struct config_file *cfg)
g_hash_table_unref (cfg->cfg_params);
g_hash_table_destroy (cfg->metrics_symbols);
g_hash_table_destroy (cfg->classifiers_symbols);
/* Free symbols groups */
cur = cfg->symbols_groups;
while (cur) {
gr = cur->data;
if (gr->symbols) {
g_list_free (gr->symbols);
}
cur = g_list_next (cur);
}
if (cfg->symbols_groups) {
g_list_free (cfg->symbols_groups);
}

if (cfg->checksum) {
g_free (cfg->checksum);
}

+ 45
- 6
src/cfg_xml.c View File

@@ -1050,15 +1050,28 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
return TRUE;
}

static gint
symbols_group_find_func (gconstpointer a, gconstpointer b)
{
const struct symbols_group *gr = a;
const gchar *uv = b;

return g_ascii_strcasecmp (gr->name, uv);
}

gboolean
handle_metric_symbol (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
{
gchar *strval, *err, *desc;
gchar *strval, *err, *desc, *group;
double *value;
GList *metric_list;
GList *metric_list, *group_list;
struct metric *metric = ctx->section_pointer;
struct symbols_group *sym_group;
struct symbol_def *sym_def;

sym_def = memory_pool_alloc (cfg->cfg_pool, sizeof (struct symbol_def));
value = memory_pool_alloc (cfg->cfg_pool, sizeof (double));

if (attrs == NULL || (strval = g_hash_table_lookup (attrs, "weight")) == NULL) {
msg_info ("symbol tag should have \"weight\" attribute, assume weight 1.0");
*value = 1.0;
@@ -1072,19 +1085,30 @@ handle_metric_symbol (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
}
}
sym_def->weight = *value;
sym_def->name = memory_pool_strdup (cfg->cfg_pool, data);

if (attrs != NULL) {
desc = g_hash_table_lookup (attrs, "description");
if (desc) {
g_hash_table_insert (metric->descriptions, data, memory_pool_strdup (cfg->cfg_pool, desc));
sym_def->description = memory_pool_strdup (cfg->cfg_pool, desc);
g_hash_table_insert (metric->descriptions, data, sym_def->description);
}
else {
sym_def->description = NULL;
}
group = g_hash_table_lookup (attrs, "group");
if (group == NULL) {
group = "ungrouped";
}
}

g_hash_table_insert (metric->symbols, data, value);
g_hash_table_insert (metric->symbols, sym_def->name, value);

if ((metric_list = g_hash_table_lookup (cfg->metrics_symbols, data)) == NULL) {
if ((metric_list = g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) {
metric_list = g_list_prepend (NULL, metric);
memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)g_list_free, metric_list);
g_hash_table_insert (cfg->metrics_symbols, data, metric_list);
g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list);
}
else {
/* Slow but keep start element of list in safe */
@@ -1093,6 +1117,21 @@ handle_metric_symbol (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
}
}

/* Search for symbol group */
group_list = g_list_find_custom (cfg->symbols_groups, group, symbols_group_find_func);
if (group_list == NULL) {
/* Create new group */
sym_group = memory_pool_alloc (cfg->cfg_pool, sizeof (struct symbols_group));
sym_group->name = memory_pool_strdup (cfg->cfg_pool, group);
sym_group->symbols = NULL;
cfg->symbols_groups = g_list_prepend (cfg->symbols_groups, sym_group);
}
else {
sym_group = group_list->data;
}
/* Insert symbol */
sym_group->symbols = g_list_prepend (sym_group->symbols, sym_def);

return TRUE;
}


+ 87
- 4
src/webui.c View File

@@ -57,6 +57,7 @@

/* HTTP paths */
#define PATH_AUTH "/login"
#define PATH_SYMBOLS "/symbols"

gpointer init_webui_worker (void);
void start_webui_worker (struct rspamd_worker *worker);
@@ -218,6 +219,16 @@ webui_ssl_init (struct rspamd_webui_worker_ctx *ctx)
}
#endif

/* Calculate and set content-length header */
static void
http_calculate_content_length (struct evbuffer *evb, struct evhttp_request *req)
{
gchar numbuf[64];

rspamd_snprintf (numbuf, sizeof (numbuf), "%z", evbuffer_get_length (evb));
evhttp_add_header(req->output_headers, "Content-Length", numbuf);
}

/* Command handlers */

/*
@@ -266,15 +277,86 @@ http_handle_auth (struct evhttp_request *req, gpointer arg)
hours = uptime / 3600;
minutes = uptime / 60 - hours * 60;
uptime -= hours * 3600 + minutes * 60;
rspamd_snprintf (uptime_buf, sizeof (uptime_buf), "%d hour%s %d minute%s %d second%s", hours, hours > 1 ? "s" : " ", minutes, minutes > 1 ? "s" : " ", (gint)uptime, uptime > 1 ? "s" : " ");
rspamd_snprintf (uptime_buf, sizeof (uptime_buf), "%d hour%s %d minute%s %d second%s", hours, hours != 1 ? "s" : " ", minutes, minutes != 1 ? "s" : " ", (gint)uptime, uptime != 1 ? "s" : " ");
}

evbuffer_add_printf (evb, "{\"auth\": \"%s\", \"version\": \"%s\", \"uptime\": \"%s\", \"error\": \"%s\"}" CRLF,
auth, RVERSION, uptime_buf, error);
evhttp_add_header(req->output_headers, "Connection", "close");
evhttp_add_header (req->output_headers, "Connection", "close");
http_calculate_content_length (evb, req);

evhttp_send_reply (req, HTTP_OK, "OK", evb);
evbuffer_free (evb);
}

/*
* Symbols command handler:
* request: /symbols
* reply: json [{
* "name": "group_name",
* "symbols": [
* {
* "name": "name",
* "weight": 0.1,
* "description": "description of symbol"
* },
* {...}
* },
* {...}]
*/
static void
http_handle_symbols (struct evhttp_request *req, gpointer arg)
{
struct rspamd_webui_worker_ctx *ctx = arg;
struct evbuffer *evb;
GList *cur_gr, *cur_sym;
struct symbols_group *gr;
struct symbol_def *sym;

evb = evbuffer_new ();
if (!evb) {
msg_err ("cannot allocate evbuffer for reply");
return;
}

/* Trailer */
evbuffer_add (evb, "[", 1);

/* Go throught all symbols groups */
cur_gr = ctx->cfg->symbols_groups;
while (cur_gr) {
gr = cur_gr->data;
evbuffer_add_printf (evb, "{\"group\":\"%s\",\"rules\":[", gr->name);
/* Iterate throught all symbols */
cur_sym = gr->symbols;
while (cur_sym) {
sym = cur_sym->data;

if (sym->description) {
evbuffer_add_printf (evb, "{\"symbol\":\"%s\",\"weight\":%.2f,\"description\":\"%s\"%s", sym->name, sym->weight,
sym->description, g_list_next (cur_sym) ? "}," : "}");
}
else {
evbuffer_add_printf (evb, "{\"symbol\":\"%s\",\"weight\":%.2f%s", sym->name, sym->weight,
g_list_next (cur_sym) ? "}," : "}");
}

cur_sym = g_list_next (cur_sym);
}
if (g_list_next (cur_gr)) {
evbuffer_add (evb, "]},", 3);
}
else {
evbuffer_add (evb, "]},", 2);
}
cur_gr = g_list_next (cur_gr);
}
evbuffer_add (evb, "]" CRLF, 3);
evhttp_add_header (req->output_headers, "Connection", "close");
http_calculate_content_length (evb, req);

evhttp_send_reply(req, HTTP_OK, "OK", evb);
evbuffer_free(evb);
evhttp_send_reply (req, HTTP_OK, "OK", evb);
evbuffer_free (evb);
}

gpointer
@@ -351,6 +433,7 @@ start_webui_worker (struct rspamd_worker *worker)

/* Add callbacks for different methods */
evhttp_set_cb (ctx->http, PATH_AUTH, http_handle_auth, ctx);
evhttp_set_cb (ctx->http, PATH_SYMBOLS, http_handle_symbols, ctx);

ctx->resolver = dns_resolver_init (ctx->ev_base, worker->srv->cfg);


Loading…
Cancel
Save