]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Use extended map types in lua map, unify code
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 May 2016 14:06:54 +0000 (15:06 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 10 May 2016 14:06:54 +0000 (15:06 +0100)
src/libutil/map.c
src/libutil/map.h
src/lua/lua_common.c
src/lua/lua_map.c

index 268c888c309c8e3e90330e75391417d0fe379411..f52844edd14ea93cf3d84ebe77cbbb6168e2225a 100644 (file)
@@ -1181,8 +1181,7 @@ rspamd_map_add (struct rspamd_config *cfg,
        map->poll_timeout = cfg->map_timeout;
 
        if (description != NULL) {
-               map->description =
-                       rspamd_mempool_strdup (cfg->cfg_pool, description);
+               map->description = g_strdup (description);
        }
 
        rspamd_map_calculate_hash (map);
@@ -1196,6 +1195,7 @@ rspamd_map_add (struct rspamd_config *cfg,
 struct rspamd_map*
 rspamd_map_add_from_ucl (struct rspamd_config *cfg,
        const ucl_object_t *obj,
+       const gchar *description,
        map_cb_t read_callback,
        map_fin_cb_t fin_callback,
        void **user_data)
@@ -1224,6 +1224,10 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg,
        map->backends = g_ptr_array_new ();
        map->poll_timeout = cfg->map_timeout;
 
+       if (description) {
+               map->description = g_strdup (description);
+       }
+
        if (ucl_object_type (obj) == UCL_ARRAY) {
                /* Add array of maps as multiple backends */
                while ((cur = ucl_object_iterate (obj, &it, true)) != NULL) {
@@ -1257,6 +1261,10 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg,
 
                elt = ucl_object_lookup (obj, "description");
                if (elt && ucl_object_type (elt) == UCL_STRING) {
+                       if (map->description) {
+                               g_free (map->description);
+                       }
+
                        map->description = g_strdup (ucl_object_tostring (elt));
                }
 
index 08a7048aa88ad08a72e4937f131336a271d740ea..3b6439efb3c82a6045449dde26ad1e78888b2823 100644 (file)
@@ -61,6 +61,7 @@ struct rspamd_map* rspamd_map_add (struct rspamd_config *cfg,
  */
 struct rspamd_map* rspamd_map_add_from_ucl (struct rspamd_config *cfg,
        const ucl_object_t *obj,
+       const gchar *description,
        map_cb_t read_callback,
        map_fin_cb_t fin_callback,
        void **user_data);
index 768b65bfce45da9570c7ca9043b60bc1226335d3..4563d9f84d7f3619ec865bff836977355d05d896 100644 (file)
@@ -677,7 +677,7 @@ rspamd_lua_parse_table_arguments (lua_State *L, gint pos,
                                        lua_pop (L, 1);
                                }
                                break;
-                       case 'u':
+                       case 'O':
                                if (t != LUA_TNONE) {
                                        *(va_arg (ap, ucl_object_t **)) = ucl_object_lua_import (L,
                                                        idx);
index e6aec7f57c327204feea61274b9cb6cd6a38150e..a74ee205c87c2b450595ef9eec3b21d35341408f 100644 (file)
@@ -345,8 +345,9 @@ gint
 lua_config_add_map (lua_State *L)
 {
        struct rspamd_config *cfg = lua_check_config (L, 1);
-       const gchar *map_line = NULL, *description = NULL;
+       const char *description = NULL;
        const gchar *type = NULL;
+       ucl_object_t *map_obj = NULL;
        struct lua_map_callback_data *cbdata;
        struct rspamd_lua_map *map, **pmap;
        struct rspamd_map *m;
@@ -354,132 +355,22 @@ lua_config_add_map (lua_State *L)
        GError *err = NULL;
 
        if (cfg) {
-               if (lua_type (L, 2) == LUA_TTABLE) {
-                       if (!rspamd_lua_parse_table_arguments (L, 2, &err,
-                                       "*type=S;description=S;callback=F;*url=S",
-                                       &type, &description, &cbidx, &map_line)) {
-                               ret = luaL_error (L, "invalid table arguments: %s", err->message);
-                               g_error_free (err);
-
-                               return ret;
-                       }
-
-                       g_assert (type != NULL && map_line != NULL);
-
-                       if (strcmp (type, "callback") == 0) {
-                               if (cbidx == -1) {
-                                       ret = luaL_error (L, "invalid table arguments: callback missing");
-                                       return ret;
-                               }
-
-                               map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
-                               map->type = RSPAMD_LUA_MAP_CALLBACK;
-                               map->data.cbdata = rspamd_mempool_alloc0 (cfg->cfg_pool,
-                                               sizeof (*map->data.cbdata));
-                               cbdata = map->data.cbdata;
-                               cbdata->L = L;
-                               cbdata->data = NULL;
-                               cbdata->lua_map = map;
-                               cbdata->ref = cbidx;
-
-                               if ((m = rspamd_map_add (cfg, map_line, description,
-                                               lua_map_read, lua_map_fin,
-                                               (void **)&map->data.cbdata)) == NULL) {
-                                       msg_warn_config ("invalid map %s", map_line);
-                                       luaL_unref (L, LUA_REGISTRYINDEX, cbidx);
-                                       lua_pushnil (L);
-
-                                       return 1;
-                               }
-                       }
-                       else if (strcmp (type, "set") == 0) {
-                               map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
-                               map->data.hash = g_hash_table_new (rspamd_strcase_hash,
-                                               rspamd_strcase_equal);
-                               map->type = RSPAMD_LUA_MAP_SET;
-
-                               if ((m = rspamd_map_add (cfg, map_line, description,
-                                               rspamd_hosts_read,
-                                               rspamd_hosts_fin,
-                                               (void **)&map->data.hash)) == NULL) {
-                                       msg_warn_config ("invalid set map %s", map_line);
-                                       g_hash_table_destroy (map->data.hash);
-                                       lua_pushnil (L);
+               if (!rspamd_lua_parse_table_arguments (L, 2, &err,
+                               "*url=O;description=S;callback=F;type=S",
+                               &map_obj, &description, &cbidx, &type)) {
+                       ret = luaL_error (L, "invalid table arguments: %s", err->message);
+                       g_error_free (err);
 
-                                       return 1;
-                               }
-                       }
-                       else if (strcmp (type, "map") == 0) {
-                               map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
-                               map->data.hash = g_hash_table_new (rspamd_strcase_hash,
-                                               rspamd_strcase_equal);
-                               map->type = RSPAMD_LUA_MAP_HASH;
-
-                               if ((m = rspamd_map_add (cfg, map_line, description,
-                                               rspamd_kv_list_read,
-                                               rspamd_kv_list_fin,
-                                               (void **)&map->data.hash)) == NULL) {
-                                       msg_warn_config ("invalid hash map %s", map_line);
-                                       g_hash_table_destroy (map->data.hash);
-                                       lua_pushnil (L);
-                                       return 1;
-                               }
-                       }
-                       else if (strcmp (type, "radix") == 0) {
-                               map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
-                               map->data.radix = radix_create_compressed ();
-                               map->type = RSPAMD_LUA_MAP_RADIX;
-
-                               if ((m = rspamd_map_add (cfg, map_line, description,
-                                               rspamd_radix_read,
-                                               rspamd_radix_fin,
-                                               (void **)&map->data.radix)) == NULL) {
-                                       msg_warn_config ("invalid radix map %s", map_line);
-                                       radix_destroy_compressed (map->data.radix);
-                                       lua_pushnil (L);
-                                       return 1;
-                               }
-                       }
-                       else if (strcmp (type, "regexp") == 0) {
-                               map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
-                               map->data.re_map = NULL;
-                               map->type = RSPAMD_LUA_MAP_REGEXP;
-
-                               if ((m = rspamd_map_add (cfg, map_line, description,
-                                               rspamd_regexp_list_read,
-                                               rspamd_regexp_list_fin,
-                                               (void **)&map->data.re_map)) == NULL) {
-                                       msg_warn_config ("invalid regexp map %s", map_line);
-                                       lua_pushnil (L);
-                                       return 1;
-                               }
-                       }
-                       else {
-                               ret = luaL_error (L, "invalid arguments: unknown type '%s'", type);
+                       return ret;
+               }
 
-                               return ret;
-                       }
+               g_assert (map_obj != NULL);
 
-                       map->map = m;
-                       pmap = lua_newuserdata (L, sizeof (void *));
-                       *pmap = map;
-                       rspamd_lua_setclass (L, "rspamd{map}", -1);
+               if (type == NULL) {
+                       type = "callback";
                }
-               else {
-                       /*
-                        * Legacy format add_map(map_line, description, callback)
-                        */
-                       map_line = luaL_checkstring (L, 2);
-
-                       if (lua_gettop (L) == 4) {
-                               description = lua_tostring (L, 3);
-                               cbidx = 4;
-                       }
-                       else {
-                               description = NULL;
-                               cbidx = 3;
-                       }
 
+               if (strcmp (type, "callback") == 0) {
                        map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
                        map->type = RSPAMD_LUA_MAP_CALLBACK;
                        map->data.cbdata = rspamd_mempool_alloc0 (cfg->cfg_pool,
@@ -488,38 +379,104 @@ lua_config_add_map (lua_State *L)
                        cbdata->L = L;
                        cbdata->data = NULL;
                        cbdata->lua_map = map;
+                       cbdata->ref = cbidx;
+
+                       if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+                                       lua_map_read, lua_map_fin,
+                                       (void **)&map->data.cbdata)) == NULL) {
 
-                       if (lua_type (L, cbidx) == LUA_TFUNCTION) {
-                               lua_pushvalue (L, cbidx);
-                               /* Get a reference */
-                               cbdata->ref = luaL_ref (L, LUA_REGISTRYINDEX);
+                               if (cbidx != -1) {
+                                       luaL_unref (L, LUA_REGISTRYINDEX, cbidx);
+                               }
+
+                               lua_pushnil (L);
+
+                               return 1;
                        }
-                       else {
-                               /*
-                                * Now we can create maps with delayed callbacks, to allow better
-                                * closures generation
-                                */
-                               cbdata->ref = -1;
+               }
+               else if (strcmp (type, "set") == 0) {
+                       map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
+                       map->data.hash = g_hash_table_new (rspamd_strcase_hash,
+                                       rspamd_strcase_equal);
+                       map->type = RSPAMD_LUA_MAP_SET;
+
+                       if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+                                       rspamd_hosts_read,
+                                       rspamd_hosts_fin,
+                                       (void **)&map->data.hash)) == NULL) {
+                               g_hash_table_destroy (map->data.hash);
+                               lua_pushnil (L);
+                               ucl_object_unref (map_obj);
+
+                               return 1;
                        }
+               }
+               else if (strcmp (type, "map") == 0) {
+                       map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
+                       map->data.hash = g_hash_table_new (rspamd_strcase_hash,
+                                       rspamd_strcase_equal);
+                       map->type = RSPAMD_LUA_MAP_HASH;
+
+                       if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+                                       rspamd_kv_list_read,
+                                       rspamd_kv_list_fin,
+                                       (void **)&map->data.hash)) == NULL) {
+                               g_hash_table_destroy (map->data.hash);
+                               lua_pushnil (L);
+                               ucl_object_unref (map_obj);
 
-                       if ((m = rspamd_map_add (cfg, map_line, description,
-                                       lua_map_read, lua_map_fin,
-                                       (void **)&map->data.cbdata)) == NULL) {
-                               msg_warn_config ("invalid map %s", map_line);
+                               return 1;
+                       }
+               }
+               else if (strcmp (type, "radix") == 0) {
+                       map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
+                       map->data.radix = radix_create_compressed ();
+                       map->type = RSPAMD_LUA_MAP_RADIX;
+
+                       if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+                                       rspamd_radix_read,
+                                       rspamd_radix_fin,
+                                       (void **)&map->data.radix)) == NULL) {
+                               radix_destroy_compressed (map->data.radix);
                                lua_pushnil (L);
+                               ucl_object_unref (map_obj);
+
+                               return 1;
                        }
-                       else {
-                               map->map = m;
-                               pmap = lua_newuserdata (L, sizeof (void *));
-                               *pmap = map;
-                               rspamd_lua_setclass (L, "rspamd{map}", -1);
+               }
+               else if (strcmp (type, "regexp") == 0) {
+                       map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*map));
+                       map->data.re_map = NULL;
+                       map->type = RSPAMD_LUA_MAP_REGEXP;
+
+                       if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description,
+                                       rspamd_regexp_list_read,
+                                       rspamd_regexp_list_fin,
+                                       (void **)&map->data.re_map)) == NULL) {
+                               lua_pushnil (L);
+                               ucl_object_unref (map_obj);
+
+                               return 1;
                        }
                }
+               else {
+                       ret = luaL_error (L, "invalid arguments: unknown type '%s'", type);
+                       ucl_object_unref (map_obj);
+
+                       return ret;
+               }
+
+               map->map = m;
+               pmap = lua_newuserdata (L, sizeof (void *));
+               *pmap = map;
+               rspamd_lua_setclass (L, "rspamd{map}", -1);
        }
        else {
                return luaL_error (L, "invalid arguments");
        }
 
+       ucl_object_unref (map_obj);
+
        return 1;
 }