From: Vsevolod Stakhov Date: Tue, 10 May 2016 14:06:54 +0000 (+0100) Subject: [Feature] Use extended map types in lua map, unify code X-Git-Tag: 1.3.0~500 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4295cb4b80992958f61a63281ba65e3a8f0516d0;p=thirdparty%2Frspamd.git [Feature] Use extended map types in lua map, unify code --- diff --git a/src/libutil/map.c b/src/libutil/map.c index 268c888c30..f52844edd1 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -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)); } diff --git a/src/libutil/map.h b/src/libutil/map.h index 08a7048aa8..3b6439efb3 100644 --- a/src/libutil/map.h +++ b/src/libutil/map.h @@ -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); diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 768b65bfce..4563d9f84d 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -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); diff --git a/src/lua/lua_map.c b/src/lua/lua_map.c index e6aec7f57c..a74ee205c8 100644 --- a/src/lua/lua_map.c +++ b/src/lua/lua_map.c @@ -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; }