Browse Source

[Feature] Use extended map types in lua map, unify code

tags/1.3.0
Vsevolod Stakhov 8 years ago
parent
commit
4295cb4b80
4 changed files with 110 additions and 144 deletions
  1. 10
    2
      src/libutil/map.c
  2. 1
    0
      src/libutil/map.h
  3. 1
    1
      src/lua/lua_common.c
  4. 98
    141
      src/lua/lua_map.c

+ 10
- 2
src/libutil/map.c View 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));
}


+ 1
- 0
src/libutil/map.h View 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);

+ 1
- 1
src/lua/lua_common.c View 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);

+ 98
- 141
src/lua/lua_map.c View 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;
}


Loading…
Cancel
Save