Project

General

Profile

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>