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