]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Controller: Allow to pass query arguments to the lua webui plugins
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 24 Apr 2020 20:29:11 +0000 (21:29 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 24 Apr 2020 20:29:11 +0000 (21:29 +0100)
src/controller.c

index e5ea56f17a1e0f78d215106f261ad4b296f378b3..8440beb8e0f9927b3023aeff7c7aa461bb2e36c7 100644 (file)
@@ -2863,7 +2863,8 @@ rspamd_controller_handle_plugins (struct rspamd_http_connection_entry *conn_ent,
                }
 
                g_assert (npath != NULL);
-               ucl_array_append (npath, ucl_object_fromstring (k));
+               rspamd_ftok_t *key_tok = (rspamd_ftok_t *)k;
+               ucl_array_append (npath, ucl_object_fromlstring (key_tok->begin, key_tok->len));
        }
 
        rspamd_controller_send_ucl (conn_ent, plugins);
@@ -2959,14 +2960,31 @@ rspamd_controller_handle_lua_plugin (struct rspamd_http_connection_entry *conn_e
        struct rspamd_http_connection_entry **pconn;
        struct rspamd_controller_worker_ctx *ctx;
        lua_State *L;
-       gchar *url_str;
+       struct http_parser_url u;
+       rspamd_ftok_t lookup;
 
-       url_str = rspamd_fstring_cstr (msg->url);
-       cbd = g_hash_table_lookup (session->ctx->plugins, url_str);
-       g_free (url_str);
+
+       http_parser_parse_url (msg->url->str, msg->url->len, TRUE, &u);
+
+       if (u.field_set & (1 << UF_PATH)) {
+               guint unnorm_len;
+               lookup.begin = msg->url->str + u.field_data[UF_PATH].off;
+               lookup.len = u.field_data[UF_PATH].len;
+
+               rspamd_http_normalize_path_inplace ((gchar *)lookup.begin,
+                               lookup.len,
+                               &unnorm_len);
+               lookup.len = unnorm_len;
+       }
+       else {
+               lookup.begin = msg->url->str;
+               lookup.len = msg->url->len;
+       }
+
+       cbd = g_hash_table_lookup (session->ctx->plugins, &lookup);
 
        if (cbd == NULL || cbd->handler == NULL) {
-               msg_err_session ("plugin handler %V has not been found", msg->url);
+               msg_err_session ("plugin handler %T has not been found", &lookup);
                rspamd_controller_send_error (conn_ent, 404, "No command associated");
                return 0;
        }
@@ -3011,15 +3029,38 @@ rspamd_controller_handle_lua_plugin (struct rspamd_http_connection_entry *conn_e
        /* Callback */
        lua_rawgeti (L, LUA_REGISTRYINDEX, cbd->handler->idx);
 
+       /* Task */
        ptask = lua_newuserdata (L, sizeof (*ptask));
        rspamd_lua_setclass (L, "rspamd{task}", -1);
        *ptask = task;
 
+       /* Connection */
        pconn = lua_newuserdata (L, sizeof (*pconn));
        rspamd_lua_setclass (L, "rspamd{csession}", -1);
        *pconn = conn_ent;
 
-       if (lua_pcall (L, 2, 0, 0) != 0) {
+       /* Query arguments */
+       GHashTable *params;
+       GHashTableIter it;
+       gpointer k, v;
+
+       params = rspamd_http_message_parse_query (msg);
+       lua_createtable (L, g_hash_table_size (params), 0);
+       g_hash_table_iter_init (&it, params);
+
+       while (g_hash_table_iter_next (&it, &k, &v)) {
+               rspamd_ftok_t *key_tok = (rspamd_ftok_t *)k,
+                       *value_tok = (rspamd_ftok_t *)v;
+
+               lua_pushlstring (L, key_tok->begin, key_tok->len);
+               /* TODO: consider rspamd_text here */
+               lua_pushlstring (L, value_tok->begin, value_tok->len);
+               lua_settable (L, -3);
+       }
+
+       g_hash_table_unref (params);
+
+       if (lua_pcall (L, 3, 0, 0) != 0) {
                rspamd_controller_send_error (conn_ent, 503, "Cannot run callback: %s",
                                lua_tostring (L, -1));
                lua_settop (L, 0);
@@ -3391,7 +3432,7 @@ rspamd_controller_register_plugin_path (lua_State *L,
 {
        struct rspamd_controller_plugin_cbdata *cbd;
        const ucl_object_t *elt;
-       GString *full_path;
+       rspamd_fstring_t *full_path;
 
        cbd = g_malloc0 (sizeof (*cbd));
        cbd->L = L;
@@ -3418,15 +3459,15 @@ rspamd_controller_register_plugin_path (lua_State *L,
                cbd->need_task = TRUE;
        }
 
-       full_path = g_string_new ("/plugins/");
-       rspamd_printf_gstring (full_path, "%s/%s",
-                       plugin_name, path);
+       full_path = rspamd_fstring_new_init ("/plugins/", sizeof ("/plugins/") - 1);
+       /* Zero terminated */
+       rspamd_printf_fstring (&full_path, "%s/%s%c",
+                       plugin_name, path, '\0');
 
        rspamd_http_router_add_path (ctx->http,
                        full_path->str,
                        rspamd_controller_handle_lua_plugin);
-       g_hash_table_insert (ctx->plugins, full_path->str, cbd);
-       g_string_free (full_path, FALSE); /* Do not free data */
+       g_hash_table_insert (ctx->plugins, rspamd_ftok_map (full_path), cbd);
 }
 
 static void
@@ -3499,9 +3540,9 @@ start_controller_worker (struct rspamd_worker *worker)
        ctx->srv = worker->srv;
        ctx->custom_commands = g_hash_table_new (rspamd_strcase_hash,
                        rspamd_strcase_equal);
-       ctx->plugins = g_hash_table_new_full (rspamd_strcase_hash,
-                               rspamd_strcase_equal, g_free,
-                               rspamd_plugin_cbdata_dtor);
+       ctx->plugins = g_hash_table_new_full (rspamd_ftok_icase_hash,
+                       rspamd_ftok_icase_equal, rspamd_fstring_mapped_ftok_free,
+                       rspamd_plugin_cbdata_dtor);
 
        if (isnan (ctx->task_timeout)) {
                if (isnan (ctx->cfg->task_timeout)) {