diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/array.lua | 16 | ||||
-rw-r--r-- | util/logger.lua | 16 | ||||
-rw-r--r-- | util/prosodyctl/shell.lua | 8 | ||||
-rw-r--r-- | util/sslconfig.lua | 73 | ||||
-rw-r--r-- | util/stanza.lua | 32 |
5 files changed, 116 insertions, 29 deletions
diff --git a/util/array.lua b/util/array.lua index c33a5ef1..9d438940 100644 --- a/util/array.lua +++ b/util/array.lua @@ -8,6 +8,7 @@ local t_insert, t_sort, t_remove, t_concat = table.insert, table.sort, table.remove, table.concat; +local t_move = require "util.table".move; local setmetatable = setmetatable; local getmetatable = getmetatable; @@ -137,13 +138,11 @@ function array_base.slice(outa, ina, i, j) return outa; end - for idx = 1, 1+j-i do - outa[idx] = ina[i+(idx-1)]; - end + + t_move(ina, i, j, 1, outa); if ina == outa then - for idx = 2+j-i, #outa do - outa[idx] = nil; - end + -- Clear (nil) remainder of range + t_move(ina, #outa+1, #outa*2, 2+j-i, ina); end return outa; end @@ -209,10 +208,7 @@ function array_methods:shuffle() end function array_methods:append(ina) - local len, len2 = #self, #ina; - for i = 1, len2 do - self[len+i] = ina[i]; - end + t_move(ina, 1, #ina, #self+1, self); return self; end diff --git a/util/logger.lua b/util/logger.lua index 20a5cef2..148b98dc 100644 --- a/util/logger.lua +++ b/util/logger.lua @@ -10,6 +10,7 @@ local pairs = pairs; local ipairs = ipairs; local require = require; +local t_remove = table.remove; local _ENV = nil; -- luacheck: std none @@ -78,6 +79,20 @@ local function add_simple_sink(simple_sink_function, levels) for _, level in ipairs(levels or {"debug", "info", "warn", "error"}) do add_level_sink(level, sink_function); end + return sink_function; +end + +local function remove_sink(sink_function) + local removed; + for level, sinks in pairs(level_sinks) do + for i = #sinks, 1, -1 do + if sinks[i] == sink_function then + t_remove(sinks, i); + removed = true; + end + end + end + return removed; end return { @@ -87,4 +102,5 @@ return { add_level_sink = add_level_sink; add_simple_sink = add_simple_sink; new = make_logger; + remove_sink = remove_sink; }; diff --git a/util/prosodyctl/shell.lua b/util/prosodyctl/shell.lua index bce27b94..0b1dd3f9 100644 --- a/util/prosodyctl/shell.lua +++ b/util/prosodyctl/shell.lua @@ -89,11 +89,15 @@ local function start(arg) --luacheck: ignore 212/arg local errors = 0; -- TODO This is weird, but works for now. client.events.add_handler("received", function(stanza) if stanza.name == "repl-output" or stanza.name == "repl-result" then + local dest = io.stdout; if stanza.attr.type == "error" then errors = errors + 1; - io.stderr:write(stanza:get_text(), "\n"); + dest = io.stderr; + end + if stanza.attr.eol == "0" then + dest:write(stanza:get_text()); else - print(stanza:get_text()); + dest:write(stanza:get_text(), "\n"); end end if stanza.name == "repl-result" then diff --git a/util/sslconfig.lua b/util/sslconfig.lua index 6074a1fb..0078365b 100644 --- a/util/sslconfig.lua +++ b/util/sslconfig.lua @@ -3,9 +3,12 @@ local type = type; local pairs = pairs; local rawset = rawset; +local rawget = rawget; +local error = error; local t_concat = table.concat; local t_insert = table.insert; local setmetatable = setmetatable; +local resolve_path = require"util.paths".resolve_relative_path; local _ENV = nil; -- luacheck: std none @@ -34,7 +37,7 @@ function handlers.options(config, field, new) options[value] = true; end end - config[field] = options; + rawset(config, field, options) end handlers.verifyext = handlers.options; @@ -70,6 +73,20 @@ finalisers.curveslist = finalisers.ciphers; -- TLS 1.3 ciphers finalisers.ciphersuites = finalisers.ciphers; +-- Path expansion +function finalisers.key(path, config) + if type(path) == "string" then + return resolve_path(config._basedir, path); + else + return nil + end +end +finalisers.certificate = finalisers.key; +finalisers.cafile = finalisers.key; +finalisers.capath = finalisers.key; +-- XXX: copied from core/certmanager.lua, but this seems odd, because it would remove a dhparam function from the config +finalisers.dhparam = finalisers.key; + -- protocol = "x" should enable only that protocol -- protocol = "x+" should enable x and later versions @@ -89,37 +106,81 @@ end -- Merge options from 'new' config into 'config' local function apply(config, new) + rawset(config, "_cache", nil); if type(new) == "table" then for field, value in pairs(new) do - (handlers[field] or rawset)(config, field, value); + -- exclude keys which are internal to the config builder + if field:sub(1, 1) ~= "_" then + (handlers[field] or rawset)(config, field, value); + end end end + return config end -- Finalize the config into the form LuaSec expects local function final(config) local output = { }; for field, value in pairs(config) do - output[field] = (finalisers[field] or id)(value); + -- exclude keys which are internal to the config builder + if field:sub(1, 1) ~= "_" then + output[field] = (finalisers[field] or id)(value, config); + end end -- Need to handle protocols last because it adds to the options list protocol(output); return output; end +local function build(config) + local cached = rawget(config, "_cache"); + if cached then + return cached, nil + end + + local ctx, err = rawget(config, "_context_factory")(config:final(), config); + if ctx then + rawset(config, "_cache", ctx); + end + return ctx, err +end + local sslopts_mt = { __index = { apply = apply; final = final; + build = build; }; + __newindex = function() + error("SSL config objects cannot be modified directly. Use :apply()") + end; }; -local function new() - return setmetatable({options={}}, sslopts_mt); + +-- passing basedir through everything is required to avoid sslconfig depending +-- on prosody.paths.config +local function new(context_factory, basedir) + return setmetatable({ + _context_factory = context_factory, + _basedir = basedir, + options={}, + }, sslopts_mt); end +local function clone(config) + local result = new(); + for k, v in pairs(config) do + -- note that we *do* copy the internal keys on clone -- we have to carry + -- both the factory and the cache with us + rawset(result, k, v); + end + return result +end + +sslopts_mt.__index.clone = clone; + return { apply = apply; final = final; - new = new; + _new = new; }; diff --git a/util/stanza.lua b/util/stanza.lua index a38f80b3..a14be5f0 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -21,6 +21,8 @@ local type = type; local s_gsub = string.gsub; local s_sub = string.sub; local s_find = string.find; +local t_move = table.move or require "util.table".move; +local t_create = require"util.table".create; local valid_utf8 = require "util.encodings".utf8.valid; @@ -275,25 +277,33 @@ function stanza_mt:find(path) end local function _clone(stanza, only_top) - local attr, tags = {}, {}; + local attr = {}; for k,v in pairs(stanza.attr) do attr[k] = v; end local old_namespaces, namespaces = stanza.namespaces; if old_namespaces then namespaces = {}; for k,v in pairs(old_namespaces) do namespaces[k] = v; end end - local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; + local tags, new; + if only_top then + tags = {}; + new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; + else + tags = t_create(#stanza.tags, 0); + new = t_create(#stanza, 4); + new.name = stanza.name; + new.attr = attr; + new.namespaces = namespaces; + new.tags = tags; + end + + setmetatable(new, stanza_mt); if not only_top then - for i=1,#stanza do - local child = stanza[i]; - if child.name then - child = _clone(child); - t_insert(tags, child); - end - t_insert(new, child); - end + t_move(stanza, 1, #stanza, 1, new); + t_move(stanza.tags, 1, #stanza.tags, 1, tags); + new:maptags(_clone); end - return setmetatable(new, stanza_mt); + return new; end local function clone(stanza, only_top) |