aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_actions_http.lua
blob: 327bd6708701b8737a85a73faba88031ab4132fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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 }