From d73636e6823fc1971256858a848fa75d0402689d Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 4 Apr 2017 12:05:58 +0100 Subject: [PATCH] [Minor] Allow to iterate mime headers as well --- src/lua/lua_mimepart.c | 96 ++++++++++++++++++++++++++++++++++++++++++ src/lua/lua_task.c | 1 + 2 files changed, 97 insertions(+) diff --git a/src/lua/lua_mimepart.c b/src/lua/lua_mimepart.c index dba53a2d7..07c389e97 100644 --- a/src/lua/lua_mimepart.c +++ b/src/lua/lua_mimepart.c @@ -307,6 +307,19 @@ LUA_FUNCTION_DEF (mimepart, get_digest); * @return {bool} true if a part has bad content type */ LUA_FUNCTION_DEF (mimepart, is_broken); +/*** + * @method mime_part:headers_foreach(callback, [params]) + * This method calls `callback` for each header that satisfies some condition. + * By default, all headers are iterated unless `callback` returns `true`. Nil or + * false means continue of iterations. + * Params could be as following: + * + * - `full`: header value is full table of all attributes @see task:get_header_full for details + * - `regexp`: return headers that satisfies the specified regexp + * @param {function} callback function from header name and header value + * @param {table} params optional parameters + */ +LUA_FUNCTION_DEF (mimepart, headers_foreach); static const struct luaL_reg mimepartlib_m[] = { LUA_INTERFACE_DEF (mimepart, get_content), @@ -325,6 +338,7 @@ static const struct luaL_reg mimepartlib_m[] = { LUA_INTERFACE_DEF (mimepart, is_broken), LUA_INTERFACE_DEF (mimepart, get_text), LUA_INTERFACE_DEF (mimepart, get_digest), + LUA_INTERFACE_DEF (mimepart, headers_foreach), {"__tostring", rspamd_lua_class_tostring}, {NULL, NULL} }; @@ -913,6 +927,88 @@ lua_mimepart_get_digest (lua_State * L) return 1; } +static gint +lua_mimepart_headers_foreach (lua_State *L) +{ + struct rspamd_mime_part *part = lua_check_mimepart (L); + gboolean full = FALSE, raw = FALSE; + struct rspamd_lua_regexp *re = NULL; + GList *cur; + struct rspamd_mime_header *hdr; + + if (part && lua_isfunction (L, 2)) { + if (lua_istable (L, 3)) { + lua_pushstring (L, "full"); + lua_gettable (L, 3); + + if (lua_isboolean (L, -1)) { + full = lua_toboolean (L, -1); + } + + lua_pop (L, 1); + + lua_pushstring (L, "raw"); + lua_gettable (L, 3); + + if (lua_isboolean (L, -1)) { + raw = lua_toboolean (L, -1); + } + + lua_pop (L, 1); + + lua_pushstring (L, "regexp"); + lua_gettable (L, 3); + + if (lua_isuserdata (L, -1)) { + re = *(struct rspamd_lua_regexp **) + rspamd_lua_check_udata (L, -1, "rspamd{regexp}"); + } + + lua_pop (L, 1); + } + + if (part->headers_order) { + cur = part->headers_order->head; + + while (cur) { + hdr = cur->data; + + if (re && re->re) { + if (!rspamd_regexp_match (re->re, hdr->name, + strlen (hdr->name),FALSE)) { + cur = g_list_next (cur); + continue; + } + } + + lua_pushvalue (L, 2); + lua_pushstring (L, hdr->name); + rspamd_lua_push_header (L, hdr, full, raw); + + if (lua_pcall (L, 3, 1, 0) != 0) { + msg_err ("call to header_foreach failed: %s", + lua_tostring (L, -1)); + lua_pop (L, 1); + break; + } + else { + if (lua_isboolean (L, -1)) { + if (lua_toboolean (L, -1)) { + lua_pop (L, 1); + break; + } + } + } + + lua_pop (L, 1); + cur = g_list_next (cur); + } + } + } + + return 0; +} + void luaopen_textpart (lua_State * L) { diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 41bf8d792..96eec1faf 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -4051,6 +4051,7 @@ lua_task_headers_foreach (lua_State *L) continue; } } + lua_pushvalue (L, 2); lua_pushstring (L, hdr->name); rspamd_lua_push_header (L, hdr, full, raw); -- 2.39.5