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
77
78
79
80
81
82
83
84
85
86
|
-- Prosody IM
-- Copyright (C) 2008-2009 Matthew Wild
-- Copyright (C) 2008-2009 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
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")
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 }
|