Lua Trigger Functions » History » Revision 2
Revision 1 (gstrauss, 2022-05-11 20:39) → Revision 2/3 (gstrauss, 2022-05-11 21:42)
h1. Lua Trigger Functions lighttpd [[Docs_ModMagnet|mod_magnet]] can be configured to send a trigger to another process when a specific event occurs. h3. lua trigger functions h4. trigger_sock: send trigger to socket <pre> function trigger_sock (addr, port, msg) -- connect and send msg to socket -- note: *blocking* connect() (and blocking send() unless msg is short) -- (caller should prefer addr "127.0.0.1" to succeed or fail fast) local socket = require("socket") local s = socket.tcp4() if (not s) then return false end s:settimeout(1) local rc = false if (s:connect(addr, port)) then local wr = s:send(msg) if (wr and wr == msg:len()) msg.len) then rc = true end end s:close() return rc end </pre> h4. trigger_fifo: send trigger to FIFO <pre> function trigger_fifo (path, msg) -- write msg to fifo; non-blocking; tries once or fails -- (requires luaposix) -- (lua-posix package or see https://github.com/luaposix/luaposix) local P = require "posix.fcntl" local fd = P.open(path, P.O_WRONLY | P.O_NONBLOCK | P.O_CLOEXEC) if (not fd) then return false end local unistd = require "posix.unistd" local wr = unistd.write(fd, msg); unistd.close(fd) return (wr and wr == msg:len()) msg.len) -- lua 5.3+ supports bitwise operations (used above) --local fd = P.open(path, P.O_WRONLY | P.O_NONBLOCK | P.O_CLOEXEC) -- lua 5.2 provides bit32 table of functions --local fd = P.open(path, bit32.bor(P.O_WRONLY, P.O_NONBLOCK, P.O_CLOEXEC)) -- luaJIT --local bit = require("bit") --local fd = P.open(path, bit.bor(P.O_WRONLY, P.O_NONBLOCK, P.O_CLOEXEC)) -- lua 5.1 needs an alternative bit operator implementation -- (if running lua 5.1 from before bit32 was backported to the lua 5.1 series) -- https://lua-users.org/wiki/BitwiseOperators --(not implemented here for lua 5.1) end </pre> h4. trigger_execp_bg: trigger command execution in background <pre> function trigger_execp_bg (path, argt) -- execute command in background (fork(), setsid(), fork(), execp()) -- (requires luaposix) -- (lua-posix package or see https://github.com/luaposix/luaposix) local unistd = require "posix.unistd" -- fork() local pid, _ = unistd.fork() if pid == nil then -- error return -1 elseif pid ~= 0 then -- parent local syswait = require "posix.sys.wait" local reaped, _, status = syswait.wait(pid) return reaped == pid and status or -1 end -- child (pid == 0) -- setsid() if (not unistd.setpid('s', 0)) then -- setsid unistd._exit(-1) end -- fork() pid, _ = unistd.fork() if pid == nil then -- error unistd._exit(-1) elseif pid ~= 0 then -- parent unistd._exit(0) end -- child (pid == 0) -- execp() unistd.execp(path, argt) unistd._exit(-1) end </pre> h3. lua trigger examples h4. thumbnail-trigger.lua The example below triggers thumbnail creation (by an external process) following successful upload of an image file. <pre> -- thumbnail-trigger.lua for lighttpd mod_magnet -- -- trigger a script to generate a thumbnail after successful PUT of an image file -- -- lighttpd.conf -- server.modules += ("mod_magnet") -- $HTTP["method"] == "PUT" { -- magnet.attract-response-start-to = ("/path/to/thumbnail-trigger.lua") -- } local r = lighty.r local req_attr = r.req_attr -- check for successful PUT request with HTTP status 201 or 204 -- lighttpd 1.4.60 - 1.4.65 (to be removed in 1.4.66) --local http_status = req_attr["response.http-status"] -- lighttpd 1.4.65+ local http_status = r.req_item.http_status if (not http_status == 201 and not http_status == 204) then return 0 end -- (method is checked in lighttpd.conf sample in comment at top) --if (not req_attr["request.method"] == "PUT") then return 0 end -- get file path components local path = req_attr["physical.path"] local dir, file, ext = string.match(path, "^(.*/)([^/]+)([.][%a%d]+)$") if (not ext) then return 0 end -- check for .jpg (or list of extensions for which to trigger) -- TODO: (as needed) if (not ext == ".jpg") then return 0 end -- string manipulation on path to get path to thumbnail -- TODO: (as needed) local thumb = dir .. "thumbs/" .. file .. ext -- trigger thumbnail update -- TODO: fill in and call chosen trigger method -- (Functions must be defined before being called) -- (e.g. copy reference code implementation into script) --trigger_sock("127.0.0.1", 8888, path .. " " .. thumb .. "\n") --trigger_fifo("/path/to/thumbnail.fifo", path .. " " .. thumb .. "\n") --trigger_execp_bg("/path/to/thumbnail.py, { path, thumb }) return 0 </pre>