mod_ping: Convert from Windows line endings
[prosody.git] / plugins / mod_actions_http.lua
1
2 local httpserver = require "net.httpserver";
3 local t_concat, t_insert = table.concat, table.insert;
4
5 local log = log;
6
7 local response_404 = { status = "404 Not Found", body = "<h1>No such action</h1>Sorry, I don't have the action you requested" };
8
9 local control = require "core.actions".actions;
10
11
12 local urlcodes = setmetatable({}, { __index = function (t, k) t[k] = string.char(tonumber("0x"..k)); return t[k]; end });
13
14 local function urldecode(s)
15                 return s and (s:gsub("+", " "):gsub("%%([a-fA-F0-9][a-fA-F0-9])", urlcodes));
16 end
17
18 local function query_to_table(query)
19         if type(query) == "string" and #query > 0 then
20                 if query:match("=") then
21                         local params = {};
22                         for k, v in query:gmatch("&?([^=%?]+)=([^&%?]+)&?") do
23                                 if k and v then
24                                         params[urldecode(k)] = urldecode(v);
25                                 end
26                         end
27                         return params;
28                 else
29                         return urldecode(query);
30                 end
31         end
32 end
33
34
35
36 local http_path = { http_base };
37 local function handle_request(method, body, request)
38         local path = request.url.path:gsub("^/[^/]+/", "");
39         
40         local curr = control;
41         
42         for comp in path:gmatch("([^/]+)") do
43                 curr = curr[comp];
44                 if not curr then
45                         return response_404;
46                 end
47         end
48         
49         if type(curr) == "table" then
50                 local s = {};
51                 for k,v in pairs(curr) do
52                         t_insert(s, tostring(k));
53                         t_insert(s, " = ");
54                         if type(v) == "function" then
55                                 t_insert(s, "action")
56                         elseif type(v) == "table" then
57                                 t_insert(s, "list");
58                         else
59                                 t_insert(s, tostring(v));
60                         end
61                         t_insert(s, "\n");
62                 end
63                 return t_concat(s);
64         elseif type(curr) == "function" then
65                 local params = query_to_table(request.url.query);
66                 params.host = request.headers.host:gsub(":%d+", "");
67                 local ok, ret1, ret2 = pcall(curr, params);
68                 if not ok then
69                         return "EPIC FAIL: "..tostring(ret1);
70                 elseif not ret1 then
71                         return "FAIL: "..tostring(ret2);
72                 else
73                         return "OK: "..tostring(ret2);
74                 end
75         end
76 end
77
78 httpserver.new{ port = 5280, base = "control", handler = handle_request, ssl = false }