Mercurial > prosody-modules
comparison mod_firewall/mod_firewall.lua @ 2518:0e1054c19f9d
mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 19 Feb 2017 21:06:57 +0000 |
| parents | 3990b1bca308 |
| children | c6fd8975704b |
comparison
equal
deleted
inserted
replaced
| 2517:3990b1bca308 | 2518:0e1054c19f9d |
|---|---|
| 45 -- Returns the input if it is safe to be used as a variable name, otherwise nil | 45 -- Returns the input if it is safe to be used as a variable name, otherwise nil |
| 46 function idsafe(name) | 46 function idsafe(name) |
| 47 return name:match("^%a[%w_]*$") | 47 return name:match("^%a[%w_]*$") |
| 48 end | 48 end |
| 49 | 49 |
| 50 local meta_funcs = { | |
| 51 bare = function (code) | |
| 52 return "jid_bare("..code..")", {"jid_bare"}; | |
| 53 end; | |
| 54 node = function (code) | |
| 55 return "(jid_split("..code.."))", {"jid_split"}; | |
| 56 end; | |
| 57 host = function (code) | |
| 58 return "(select(2, jid_split("..code..")))", {"jid_split"}; | |
| 59 end; | |
| 60 resource = function (code) | |
| 61 return "(select(3, jid_split("..code..")))", {"jid_split"}; | |
| 62 end; | |
| 63 }; | |
| 64 | |
| 50 -- Run quoted (%q) strings through this to allow them to contain code. e.g.: LOG=Received: $(stanza:top_tag()) | 65 -- Run quoted (%q) strings through this to allow them to contain code. e.g.: LOG=Received: $(stanza:top_tag()) |
| 51 function meta(s, extra) | 66 function meta(s, deps, extra) |
| 52 return (s:gsub("$(%b())", function (expr) | 67 return (s:gsub("$(%b())", function (expr) |
| 53 expr = expr:gsub("\\(.)", "%1"); | 68 expr = expr:gsub("\\(.)", "%1"); |
| 54 return [["..tostring(]]..expr..[[).."]]; | 69 return [["..tostring(]]..expr..[[).."]]; |
| 55 end) | 70 end) |
| 56 :gsub("$(%b<>)", function (expr) | 71 :gsub("$(%b<>)", function (expr) |
| 57 expr = expr:sub(2,-2); | 72 expr = expr:sub(2,-2); |
| 58 local default = expr:match("||([^|]+)$"); | 73 local func_chain = expr:match("|[%w|]+$"); |
| 59 if default then | 74 if func_chain then |
| 60 expr = expr:sub(1, -(#default+2)); | 75 expr = expr:sub(1, -1-#func_chain); |
| 76 end | |
| 77 local code; | |
| 78 if expr:match("^@") then | |
| 79 -- Skip stanza:find() for simple attribute lookup | |
| 80 local attr_name = expr:sub(2); | |
| 81 if deps and (attr_name == "to" or attr_name == "from" or attr_name == "type") then | |
| 82 -- These attributes may be cached in locals | |
| 83 code = attr_name; | |
| 84 table.insert(deps, attr_name); | |
| 85 else | |
| 86 code = "stanza.attr["..("%q"):format(attr_name).."]"; | |
| 87 end | |
| 61 else | 88 else |
| 62 default = "<undefined>"; | 89 code = "(stanza:find("..("%q"):format(expr)..") or "..("%q"):format("<undefined>")..")"; |
| 63 end | 90 end |
| 64 if expr:match("^@") then | 91 if func_chain then |
| 65 return "\"..(stanza.attr["..("%q"):format(expr:sub(2)).."] or "..("%q"):format(default)..")..\""; | 92 for func_name in func_chain:gmatch("|(%w+)") do |
| 66 end | 93 if code == "to" or code == "from" then |
| 67 return "\"..(stanza:find("..("%q"):format(expr)..") or "..("%q"):format(default)..")..\""; | 94 if func_name == "bare" then |
| 95 code = "bare_"..code; | |
| 96 table.insert(deps, code); | |
| 97 elseif func_name == "node" or func_name == "host" or func_name == "resource" then | |
| 98 table.insert(deps, "split_"..code); | |
| 99 code = code.."_"..func_name; | |
| 100 end | |
| 101 else | |
| 102 assert(meta_funcs[func_name], "unknown function: "..func_name); | |
| 103 local new_code, new_deps = meta_funcs[func_name](code); | |
| 104 code = new_code; | |
| 105 if new_deps and #new_deps > 0 then | |
| 106 assert(deps, "function not supported here: "..func_name); | |
| 107 for _, dep in ipairs(new_deps) do | |
| 108 table.insert(deps, dep); | |
| 109 end | |
| 110 end | |
| 111 end | |
| 112 end | |
| 113 end | |
| 114 return "\"..(("..code..") or \"<undefined>\")..\""; | |
| 68 end) | 115 end) |
| 69 :gsub("$$(%a+)", extra or {}) | 116 :gsub("$$(%a+)", extra or {}) |
| 70 :gsub([[^""%.%.]], "") | 117 :gsub([[^""%.%.]], "") |
| 71 :gsub([[%.%.""$]], "")); | 118 :gsub([[%.%.""$]], "")); |
| 72 end | 119 end |
