Add mod_actions_http for executing actions through HTTP
authorMatthew Wild <mwild1@gmail.com>
Mon, 12 Jan 2009 04:09:02 +0000 (04:09 +0000)
committerMatthew Wild <mwild1@gmail.com>
Mon, 12 Jan 2009 04:09:02 +0000 (04:09 +0000)
plugins/mod_actions_http.lua [new file with mode: 0644]

diff --git a/plugins/mod_actions_http.lua b/plugins/mod_actions_http.lua
new file mode 100644 (file)
index 0000000..327bd67
--- /dev/null
@@ -0,0 +1,76 @@
+
+local httpserver = require "net.httpserver";
+local t_concat, t_insert = table.concat, table.insert;
+
+local log = log;
+
+local response_404 = { status = "404 Not Found", body = "<h1>No such action</h1>Sorry, I don't have the action you requested" };
+
+local control = require "core.actions".actions;
+
+
+local urlcodes = setmetatable({}, { __index = function (t, k) t[k] = string.char(tonumber("0x"..k)); return t[k]; end });
+
+local function urldecode(s)
+                return s and (s:gsub("+", " "):gsub("%%([a-fA-F0-9][a-fA-F0-9])", urlcodes));
+end
+
+local function query_to_table(query)
+        if type(query) == "string" and #query > 0 then
+                if query:match("=") then
+                        local params = {};
+                        for k, v in query:gmatch("&?([^=%?]+)=([^&%?]+)&?") do
+                                if k and v then
+                                        params[urldecode(k)] = urldecode(v);
+                                end
+                        end
+                        return params;
+                else
+                        return urldecode(query);
+                end
+        end
+end
+
+
+
+local http_path = { http_base };
+local function handle_request(method, body, request)
+       local path = request.url.path:gsub("^/[^/]+/", "");
+       
+       local curr = control;
+       
+       for comp in path:gmatch("([^/]+)") do
+               curr = curr[comp];
+               if not curr then
+                       return response_404;
+               end
+       end
+       
+       if type(curr) == "table" then
+               local s = {};
+               for k,v in pairs(curr) do
+                       t_insert(s, tostring(k));
+                       t_insert(s, " = ");
+                       if type(v) == "function" then
+                               t_insert(s, "action")
+                       else
+                               t_insert(s, tostring(v));
+                       end
+                       t_insert(s, "\n");
+               end
+               return t_concat(s);
+       elseif type(curr) == "function" then
+               local params = query_to_table(request.url.query);
+               params.host = request.headers.host:gsub(":%d+", "");
+               local ok, ret1, ret2 = pcall(curr, params);
+               if not ok then
+                       return "EPIC FAIL: "..tostring(ret1);
+               elseif not ret1 then
+                       return "FAIL: "..tostring(ret2);
+               else
+                       return "OK: "..tostring(ret2);
+               end
+       end
+end
+
+httpserver.new{ port = 5280, base = "control", handler = handle_request, ssl = false }
\ No newline at end of file