aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/modulemanager.lua6
-rw-r--r--net/dns.lua2
-rw-r--r--net/httpserver.lua8
-rwxr-xr-xprosodyctl22
-rw-r--r--util/pluginloader.lua38
5 files changed, 66 insertions, 10 deletions
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index 6440f8b8..65a38ccb 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -175,7 +175,7 @@ function is_loaded(host, name)
end
function unload(host, name, ...)
- local mod = get_module(host, name);
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
if module_has_method(mod, "unload") then
@@ -282,7 +282,7 @@ function module_has_method(module, method)
end
function call_module_method(module, method, ...)
- if module_has_method(module, method) then
+ if module_has_method(module, method) then
local f = module.module[method];
return pcall(f, ...);
else
@@ -291,7 +291,7 @@ function call_module_method(module, method, ...)
end
----- API functions exposed to modules -----------
--- Must all be in api.*
+-- Must all be in api.*
-- Returns the name of the current module
function api:get_name()
diff --git a/net/dns.lua b/net/dns.lua
index c50e893c..2c008940 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -726,7 +726,7 @@ function resolver:receive(rset) -- - - - - - - - - - - - - - - - - receive
local packet = sock:receive();
if packet then
response = self:decode(packet);
- if response and self.active[response.header.id]
+ if response and self.active[response.header.id]
and self.active[response.header.id][response.question.raw] then
--print('received response');
--self.print(response);
diff --git a/net/httpserver.lua b/net/httpserver.lua
index 51dca166..654025ba 100644
--- a/net/httpserver.lua
+++ b/net/httpserver.lua
@@ -23,6 +23,9 @@ local urlencode = function (s) return s and (s:gsub("%W", function (c) return st
local log = require "util.logger".init("httpserver");
+-- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?)
+local mime_map = { html = "text/html", txt = "plain/text; charset=utf-8", js = "text/javascript" };
+
local http_servers = {};
module "httpserver"
@@ -65,6 +68,9 @@ local function send_response(request, response)
resp = { "HTTP/1.0 200 OK\r\n" };
t_insert(resp, "Connection: close\r\n");
+ t_insert(resp, "Content-Type: ");
+ t_insert(resp, mime_map[request.url.path:match("%.(%w+)")] or "application/octet-stream");
+ t_insert(resp, "\r\n");
t_insert(resp, "Content-Length: ");
t_insert(resp, #response);
t_insert(resp, "\r\n\r\n");
@@ -210,7 +216,7 @@ end
function new_request(handler)
return { handler = handler, conn = handler.socket,
write = function (...) return handler:write(...); end, state = "request",
- server = http_servers[handler.serverport()],
+ server = http_servers[handler:serverport()],
send = send_response,
destroy = destroy_request,
id = tostring{}:match("%x+$")
diff --git a/prosodyctl b/prosodyctl
index 522ebde9..8f79046f 100755
--- a/prosodyctl
+++ b/prosodyctl
@@ -462,6 +462,28 @@ function commands.unregister(arg)
return 1;
end
+function commands.addplugin(arg)
+ local url = arg[1];
+ if url:match("^http://") then
+ local http = require "socket.http";
+ show_message("Fetching...");
+ local code, err = http.request(url);
+ if not code then
+ show_message("Failed: "..err);
+ return 1;
+ end
+ if url:match("%.lua$") then
+ local ok, err = datamanager.store(url:match("/mod_([^/]+)$"), "*", "plugins", {code});
+ if not ok then
+ show_message("Failed to save to data store: "..err);
+ return 1;
+ end
+ end
+ show_message("Saved. Don't forget to load the module using the config file or admin console!");
+ else
+ show_message("Sorry, I don't understand how to fetch plugins from there.");
+ end
+end
---------------------
diff --git a/util/pluginloader.lua b/util/pluginloader.lua
index 696af34f..cffc4dfc 100644
--- a/util/pluginloader.lua
+++ b/util/pluginloader.lua
@@ -9,11 +9,19 @@
local plugin_dir = CFG_PLUGINDIR or "./plugins/";
-local io_open = io.open;
-local loadstring = loadstring;
+local io_open, os_time = io.open, os.time;
+local loadstring, pairs = loadstring, pairs;
+
+local datamanager = require "util.datamanager";
module "pluginloader"
+local function load_from_datastore(name)
+ local content = datamanager.load(name, "*", "plugins");
+ if not content or not content[1] then return nil, "Resource not found"; end
+ return content[1], name;
+end
+
local function load_file(name)
local file, err = io_open(plugin_dir..name);
if not file then return file, err; end
@@ -22,16 +30,36 @@ local function load_file(name)
return content, name;
end
-function load_resource(plugin, resource)
+function load_resource(plugin, resource, loader)
if not resource then
resource = "mod_"..plugin..".lua";
end
- local content, err = load_file(plugin.."/"..resource);
- if not content then content, err = load_file(resource); end
+ loader = loader or load_file;
+
+ local content, err = loader(plugin.."/"..resource);
+ if not content then content, err = loader(resource); end
-- TODO add support for packed plugins
+
+ if not content and loader == load_file then
+ return load_resource(plugin, resource, load_from_datastore);
+ end
+
return content, err;
end
+function store_resource(plugin, resource, content, metadata)
+ if not resource then
+ resource = "mod_"..plugin..".lua";
+ end
+ local store = { content };
+ if metadata then
+ for k,v in pairs(metadata) do
+ store[k] = v;
+ end
+ end
+ datamanager.store(plugin.."/"..resource, "*", "plugins", store);
+end
+
function load_code(plugin, resource)
local content, err = load_resource(plugin, resource);
if not content then return content, err; end