summaryrefslogtreecommitdiffstats
path: root/daemon/lua/kluautil.lua
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/lua/kluautil.lua')
-rw-r--r--daemon/lua/kluautil.lua94
1 files changed, 94 insertions, 0 deletions
diff --git a/daemon/lua/kluautil.lua b/daemon/lua/kluautil.lua
new file mode 100644
index 0000000..d8569b9
--- /dev/null
+++ b/daemon/lua/kluautil.lua
@@ -0,0 +1,94 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+local ffi = require('ffi')
+local kluautil = {}
+
+-- Get length of table
+function kluautil.kr_table_len(t)
+ if type(t) ~= 'table' then
+ return nil
+ end
+
+ local len = 0
+ for _ in pairs(t) do
+ len = len + 1
+ end
+ return len
+end
+
+-- pack varargs including nil arguments into a table
+function kluautil.kr_table_pack(...)
+ local tab = {...}
+ tab.n = select('#', ...)
+ return tab
+end
+
+-- unpack table produced by kr_table_pack and including nil values
+function kluautil.kr_table_unpack(tab)
+ return unpack(tab, 1, tab.n)
+end
+
+-- Fetch over HTTPS
+function kluautil.kr_https_fetch(url, out_file, ca_file)
+ local http_ok, http_request = pcall(require, 'http.request')
+ local httptls_ok, http_tls = pcall(require, 'http.tls')
+ local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
+
+ if not http_ok or not httptls_ok or not openssl_ok then
+ return nil, 'error: lua-http and luaossl libraries are missing (but required)'
+ end
+ local cqerrno = require('cqueues.errno')
+
+ assert(string.match(url, '^https://'))
+
+ local req = http_request.new_from_uri(url)
+ req.tls = true
+ if ca_file then
+ req.ctx = openssl_ctx.new()
+ local store = req.ctx:getStore()
+ local load_ok, errmsg = pcall(store.add, store, ca_file)
+ if not load_ok then
+ return nil, errmsg
+ end
+ else -- use defaults
+ req.ctx = http_tls.new_client_context()
+ end
+
+ req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
+
+ local headers, stream, errmsg = req:go()
+ if not headers then
+ errmsg = errmsg or 'unknown error'
+ if type(errmsg) == 'number' then
+ errmsg = cqerrno.strerror(errmsg) ..
+ ' (' .. tostring(errmsg) .. ')'
+ end
+ return nil, 'HTTP client library error: ' .. errmsg
+ end
+ if headers:get(':status') ~= "200" then
+ return nil, 'HTTP status != 200, got ' .. headers:get(':status')
+ end
+
+ local err
+ err, errmsg = stream:save_body_to_file(out_file)
+ if err == nil then
+ return nil, errmsg
+ end
+
+ out_file:seek('set', 0)
+
+ return true
+end
+
+-- Copy a lua string to C (to knot_mm_t or nil=malloc, zero-terminated).
+function kluautil.kr_string2c(str, mempool)
+ if str == nil then return nil end
+ local result = ffi.C.mm_realloc(mempool, nil, #str + 1, 0)
+ if result == nil then panic("not enough memory") end
+ ffi.copy(result, str)
+ return ffi.cast('const char *', result)
+end
+
+kluautil.list_dir = kluautil_list_dir
+
+return kluautil