Merge 0.10->trunk
authorKim Alvefur <zash@zash.se>
Mon, 24 Apr 2017 14:19:49 +0200
changeset 8124 a33a87f13155
parent 8115 d8ecefcb7c97 (current diff)
parent 8123 3c5f0cb4381a (diff)
child 8131 c14513401d65
Merge 0.10->trunk
net/http.lua
plugins/mod_posix.lua
prosodyctl
--- a/net/http.lua	Fri Apr 21 15:22:17 2017 +0200
+++ b/net/http.lua	Mon Apr 24 14:19:49 2017 +0200
@@ -10,6 +10,7 @@
 local url = require "socket.url"
 local httpstream_new = require "net.http.parser".new;
 local util_http = require "util.http";
+local events = require "util.events";
 
 local ssl_available = pcall(require, "ssl");
 
@@ -122,8 +123,9 @@
 	return ...;
 end
 
-local function request(u, ex, callback)
+local function request(self, u, ex, callback)
 	local req = url.parse(u);
+	req.url = u;
 
 	if not (req and req.host) then
 		callback("invalid-url", 0, req);
@@ -136,6 +138,15 @@
 
 	req.id = ex and ex.id or make_id(req);
 
+	do
+		local event = { http = self, url = u, request = req, options = ex, callback = callback };
+		local ret = self.events.fire_event("pre-request", event);
+		if ret then
+			return ret;
+		end
+		req, u, ex, callback = event.request, event.url, event.options, event.callback;
+	end
+
 	local method, headers, body;
 
 	local host, port = req.host, req.port;
@@ -190,13 +201,20 @@
 
 	local handler, conn = server.addclient(host, port_number, listener, "*a", sslctx)
 	if not handler then
+		self.events.fire_event("request-connection-error", { http = self, request = req, url = u, err = conn });
 		callback(conn, 0, req);
 		return nil, conn;
 	end
 	req.handler, req.conn = handler, conn
 	req.write = function (...) return req.handler:write(...); end
 
-	req.callback = function (content, code, request, response)
+	req.callback = function (content, code, response, request)
+		do
+			local event = { http = self, url = u, request = req, response = response, content = content, code = code, callback = callback };
+			self.events.fire_event("response", event);
+			content, code, response = event.content, event.code, event.response;
+		end
+
 		log("debug", "Request '%s': Calling callback, status %s", req.id, code or "---");
 		return log_if_failed(req.id, xpcall(function () return callback(content, code, request, response) end, handleerr));
 	end
@@ -204,12 +222,32 @@
 	req.state = "status";
 
 	requests[req.handler] = req;
+
+	self.events.fire_event("request", { http = self, request = req, url = u });
 	return req;
 end
 
+local function new(options)
+	local http = {
+		options = options;
+		request = request;
+		new = options and function (new_options)
+			return new(setmetatable(new_options, { __index = options }));
+		end or new;
+		events = events.new();
+		request = request;
+	};
+	return http;
+end
+
+local default_http = new();
+
 return {
-	request = request;
-
+	request = function (u, ex, callback)
+		return default_http:request(u, ex, callback);
+	end;
+	new = new;
+	events = default_http.events;
 	-- COMPAT
 	urlencode = util_http.urlencode;
 	urldecode = util_http.urldecode;
--- a/plugins/mod_posix.lua	Fri Apr 21 15:22:17 2017 +0200
+++ b/plugins/mod_posix.lua	Mon Apr 24 14:19:49 2017 +0200
@@ -57,7 +57,7 @@
 if not prosody.start_time then -- server-starting
 	local suid = module:get_option("setuid");
 	if not suid or suid == 0 or suid == "root" then
-		if pposix.getuid() == 0 and not module:get_option("run_as_root") then
+		if pposix.getuid() == 0 and not module:get_option_boolean("run_as_root") then
 			module:log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!");
 			module:log("error", "For more information on running Prosody as root, see https://prosody.im/doc/root");
 			prosody.shutdown("Refusing to run as root");
--- a/prosodyctl	Fri Apr 21 15:22:17 2017 +0200
+++ b/prosodyctl	Mon Apr 24 14:19:49 2017 +0200
@@ -873,19 +873,21 @@
 		owner = config.get("*", "prosody_user") or "prosody";
 		group = config.get("*", "prosody_group") or owner;
 	end
+	local imported = {};
 	for _, host in ipairs(hostnames) do
 		for _, dir in ipairs(arg) do
 			if lfs.attributes(dir .. "/" .. host .. "/fullchain.pem")
 			and lfs.attributes(dir .. "/" .. host .. "/privkey.pem") then
 				copy(dir .. "/" .. host .. "/fullchain.pem", cert_basedir .. "/" .. host .. ".crt", nil, owner, group);
 				copy(dir .. "/" .. host .. "/privkey.pem", cert_basedir .. "/" .. host .. ".key", "0377", owner, group);
-				show_message("Imported certificate and key for "..host);
+				table.insert(imported, host);
 			elseif lfs.attributes(dir .. "/" .. host .. ".crt")
 			and lfs.attributes(dir .. "/" .. host .. ".key") then
 				copy(dir .. "/" .. host .. ".crt", cert_basedir .. "/" .. host .. ".crt", nil, owner, group);
 				copy(dir .. "/" .. host .. ".key", cert_basedir .. "/" .. host .. ".key", "0377", owner, group);
-				show_message("Imported certificate and key for "..host);
+				table.insert(imported, host);
 			else
+				-- TODO Say where we looked
 				show_warning("No certificate for host "..host.." found :(");
 			end
 			-- TODO Additional checks
@@ -893,6 +895,16 @@
 			-- Private key matches public key in certificate
 		end
 	end
+	if imported[1] then
+		show_message("Imported certificate and key for hosts "..table.concat(imported, ", "));
+		local ok, err = prosodyctl.reload();
+		if not ok and err ~= "not-running" then
+			show_message(error_messages[err]);
+		end
+	else
+		show_warning("No certificates imported :(");
+		return 1;
+	end
 end
 
 function commands.cert(arg)