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 = "
No such action
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")
elseif type(v) == "table" then
t_insert(s, "list");
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 }