Merge 0.9->trunk
authorMatthew Wild <mwild1@gmail.com>
Tue, 23 Apr 2013 15:14:47 +0100
changeset 5511 764bda4b28b8
parent 5497 b42781a96174 (current diff)
parent 5510 3758898cefdd (diff)
child 5512 6ebea1e6795b
Merge 0.9->trunk
--- a/core/moduleapi.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/core/moduleapi.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -338,7 +338,7 @@
 end
 
 function api:open_store(name, type)
-	return storagemanager.open(self.host, name, type);
+	return storagemanager.open(self.host, name or self.name, type);
 end
 
 return api;
--- a/core/storagemanager.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/core/storagemanager.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -86,7 +86,7 @@
 	if not ret then
 		if err == "unsupported-store" then
 			log("debug", "Storage driver %s does not support store %s (%s), falling back to null driver",
-				driver_name, store, typ);
+				driver_name, store, typ or "<nil>");
 			ret = null_storage_driver;
 			err = nil;
 		end
--- a/net/http.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/net/http.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -17,9 +17,9 @@
 local server = require "net.server"
 
 local t_insert, t_concat = table.insert, table.concat;
-local pairs, ipairs = pairs, ipairs;
-local tonumber, tostring, xpcall, select, debug_traceback, char, format =
-      tonumber, tostring, xpcall, select, debug.traceback, string.char, string.format;
+local pairs = pairs;
+local tonumber, tostring, xpcall, select, traceback =
+      tonumber, tostring, xpcall, select, debug.traceback;
 
 local log = require "util.logger".init("http");
 
@@ -101,7 +101,7 @@
 	request.parser:feed(data);
 end
 
-local function handleerr(err) log("error", "Traceback[http]: %s: %s", tostring(err), debug_traceback()); end
+local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); end
 function request(u, ex, callback)
 	local req = url.parse(u);
 	
--- a/net/http/server.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/net/http/server.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -9,7 +9,7 @@
 local s_upper = string.upper;
 local setmetatable = setmetatable;
 local xpcall = xpcall;
-local debug = debug;
+local traceback = debug.traceback;
 local tostring = tostring;
 local codes = require "net.http.codes";
 
@@ -27,8 +27,11 @@
 	return wildcard_event:sub(1, -2) == event:sub(1, #wildcard_event-1);
 end
 
+local recent_wildcard_events, max_cached_wildcard_events = {}, 10000;
+
 local event_map = events._event_map;
 setmetatable(events._handlers, {
+	-- Called when firing an event that doesn't exist (but may match a wildcard handler)
 	__index = function (handlers, curr_event)
 		if is_wildcard_event(curr_event) then return; end -- Wildcard events cannot be fired
 		-- Find all handlers that could match this event, sort them
@@ -58,6 +61,12 @@
 			handlers_array = false;
 		end
 		rawset(handlers, curr_event, handlers_array);
+		if not event_map[curr_event] then -- Only wildcard handlers match, if any
+			table.insert(recent_wildcard_events, curr_event);
+			if #recent_wildcard_events > max_cached_wildcard_events then
+				rawset(handlers, table.remove(recent_wildcard_events, 1), nil);
+			end
+		end
 		return handlers_array;
 	end;
 	__newindex = function (handlers, curr_event, handlers_array)
@@ -79,7 +88,7 @@
 local function _handle_request() return handle_request(_1, _2, _3); end
 
 local last_err;
-local function _traceback_handler(err) last_err = err; log("error", "Traceback[http]: %s: %s", tostring(err), debug.traceback()); end
+local function _traceback_handler(err) last_err = err; log("error", "Traceback[httpserver]: %s", traceback(tostring(err), 2)); end
 events.add_handler("http-error", function (error)
 	return "Error processing request: "..codes[error.code]..". Check your error log for more information.";
 end, -1);
--- a/plugins/mod_auth_internal_hashed.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_auth_internal_hashed.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -7,13 +7,14 @@
 -- COPYING file in the source package for more information.
 --
 
-local datamanager = require "util.datamanager";
 local log = require "util.logger".init("auth_internal_hashed");
 local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1;
 local usermanager = require "core.usermanager";
 local generate_uuid = require "util.uuid".generate;
 local new_sasl = require "util.sasl".new;
 
+local accounts = module:open_store("accounts");
+
 local to_hex;
 do
 	local function replace_byte_with_hex(byte)
@@ -44,7 +45,7 @@
 log("debug", "initializing internal_hashed authentication provider for host '%s'", host);
 
 function provider.test_password(username, password)
-	local credentials = datamanager.load(username, host, "accounts") or {};
+	local credentials = accounts:get(username) or {};
 
 	if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
 		if credentials.password ~= password then
@@ -75,7 +76,7 @@
 end
 
 function provider.set_password(username, password)
-	local account = datamanager.load(username, host, "accounts");
+	local account = accounts:get(username);
 	if account then
 		account.salt = account.salt or generate_uuid();
 		account.iteration_count = account.iteration_count or iteration_count;
@@ -87,13 +88,13 @@
 		account.server_key = server_key_hex
 
 		account.password = nil;
-		return datamanager.store(username, host, "accounts", account);
+		return accounts:set(username, account);
 	end
 	return nil, "Account not available.";
 end
 
 function provider.user_exists(username)
-	local account = datamanager.load(username, host, "accounts");
+	local account = accounts:get(username);
 	if not account then
 		log("debug", "account not found for username '%s' at host '%s'", username, host);
 		return nil, "Auth failed. Invalid username";
@@ -102,22 +103,22 @@
 end
 
 function provider.users()
-	return datamanager.users(host, "accounts");
+	return accounts:users();
 end
 
 function provider.create_user(username, password)
 	if password == nil then
-		return datamanager.store(username, host, "accounts", {});
+		return accounts:set(username, {});
 	end
 	local salt = generate_uuid();
 	local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, salt, iteration_count);
 	local stored_key_hex = to_hex(stored_key);
 	local server_key_hex = to_hex(server_key);
-	return datamanager.store(username, host, "accounts", {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count});
+	return accounts:set(username, {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count});
 end
 
 function provider.delete_user(username)
-	return datamanager.store(username, host, "accounts", nil);
+	return accounts:set(username, nil);
 end
 
 function provider.get_sasl_handler()
@@ -126,11 +127,11 @@
 			return usermanager.test_password(username, realm, password), true;
 		end,
 		scram_sha_1 = function(sasl, username, realm)
-			local credentials = datamanager.load(username, host, "accounts");
+			local credentials = accounts:get(username);
 			if not credentials then return; end
 			if credentials.password then
 				usermanager.set_password(username, credentials.password, host);
-				credentials = datamanager.load(username, host, "accounts");
+				credentials = accounts:get(username);
 				if not credentials then return; end
 			end
 			
--- a/plugins/mod_auth_internal_plain.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_auth_internal_plain.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -6,20 +6,21 @@
 -- COPYING file in the source package for more information.
 --
 
-local datamanager = require "util.datamanager";
 local usermanager = require "core.usermanager";
 local new_sasl = require "util.sasl".new;
 
 local log = module._log;
 local host = module.host;
 
+local accounts = module:open_store("accounts");
+
 -- define auth provider
 local provider = {};
 log("debug", "initializing internal_plain authentication provider for host '%s'", host);
 
 function provider.test_password(username, password)
-	log("debug", "test password '%s' for user %s at host %s", password, username, host);
-	local credentials = datamanager.load(username, host, "accounts") or {};
+	log("debug", "test password for user %s at host %s", username, host);
+	local credentials = accounts:get(username) or {};
 
 	if password == credentials.password then
 		return true;
@@ -30,20 +31,20 @@
 
 function provider.get_password(username)
 	log("debug", "get_password for username '%s' at host '%s'", username, host);
-	return (datamanager.load(username, host, "accounts") or {}).password;
+	return (accounts:get(username) or {}).password;
 end
 
 function provider.set_password(username, password)
-	local account = datamanager.load(username, host, "accounts");
+	local account = accounts:get(username);
 	if account then
 		account.password = password;
-		return datamanager.store(username, host, "accounts", account);
+		return accounts:set(username, account);
 	end
 	return nil, "Account not available.";
 end
 
 function provider.user_exists(username)
-	local account = datamanager.load(username, host, "accounts");
+	local account = accounts:get(username);
 	if not account then
 		log("debug", "account not found for username '%s' at host '%s'", username, host);
 		return nil, "Auth failed. Invalid username";
@@ -52,15 +53,15 @@
 end
 
 function provider.users()
-	return datamanager.users(host, "accounts");
+	return accounts:users();
 end
 
 function provider.create_user(username, password)
-	return datamanager.store(username, host, "accounts", {password = password});
+	return accounts:set(username, {password = password});
 end
 
 function provider.delete_user(username)
-	return datamanager.store(username, host, "accounts", nil);
+	return accounts:set(username, nil);
 end
 
 function provider.get_sasl_handler()
--- a/plugins/mod_c2s.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_c2s.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -116,7 +116,7 @@
 	end
 end
 
-local function handleerr(err) log("error", "Traceback[c2s]: %s: %s", tostring(err), traceback()); end
+local function handleerr(err) log("error", "Traceback[c2s]: %s", traceback(tostring(err), 2)); end
 function stream_callbacks.handlestanza(session, stanza)
 	stanza = session.filter("stanzas/in", stanza);
 	if stanza then
--- a/plugins/mod_privacy.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_privacy.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -10,7 +10,6 @@
 module:add_feature("jabber:iq:privacy");
 
 local st = require "util.stanza";
-local datamanager = require "util.datamanager";
 local bare_sessions, full_sessions = prosody.bare_sessions, prosody.full_sessions;
 local util_Jid = require "util.jid";
 local jid_bare = util_Jid.bare;
@@ -18,6 +17,8 @@
 local load_roster = require "core.rostermanager".load_roster;
 local to_number = tonumber;
 
+local privacy_storage = module:open_store();
+
 function isListUsed(origin, name, privacy_lists)
 	local user = bare_sessions[origin.username.."@"..origin.host];
 	if user then
@@ -217,7 +218,7 @@
 	if stanza.attr.to == nil then -- only service requests to own bare JID
 		local query = stanza.tags[1]; -- the query element
 		local valid = false;
-		local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or { lists = {} };
+		local privacy_lists = privacy_storage:get(origin.username) or { lists = {} };
 
 		if privacy_lists.lists[1] then -- Code to migrate from old privacy lists format, remove in 0.8
 			module:log("info", "Upgrading format of stored privacy lists for %s@%s", origin.username, origin.host);
@@ -272,7 +273,7 @@
 			end
 			origin.send(st.error_reply(stanza, valid[1], valid[2], valid[3]));
 		else
-			datamanager.store(origin.username, origin.host, "privacy", privacy_lists);
+			privacy_storage:set(origin.username, privacy_lists);
 		end
 		return true;
 	end
@@ -280,7 +281,7 @@
 
 function checkIfNeedToBeBlocked(e, session)
 	local origin, stanza = e.origin, e.stanza;
-	local privacy_lists = datamanager.load(session.username, session.host, "privacy") or {};
+	local privacy_lists = privacy_storage:get(session.username) or {};
 	local bare_jid = session.username.."@"..session.host;
 	local to = stanza.attr.to or bare_jid;
 	local from = stanza.attr.from;
--- a/plugins/mod_private.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_private.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -9,7 +9,7 @@
 
 local st = require "util.stanza"
 
-local datamanager = require "util.datamanager"
+local private_storage = module:open_store();
 
 module:add_feature("jabber:iq:private");
 
@@ -20,7 +20,7 @@
 	if #query.tags == 1 then
 		local tag = query.tags[1];
 		local key = tag.name..":"..tag.attr.xmlns;
-		local data, err = datamanager.load(origin.username, origin.host, "private");
+		local data, err = private_storage:get(origin.username);
 		if err then
 			origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
 			return true;
@@ -39,7 +39,7 @@
 				data[key] = st.preserialize(tag);
 			end
 			-- TODO delete datastore if empty
-			if datamanager.store(origin.username, origin.host, "private", data) then
+			if private_storage:set(origin.username, data) then
 				origin.send(st.reply(stanza));
 			else
 				origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
--- a/plugins/mod_register.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_register.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -8,7 +8,6 @@
 
 
 local st = require "util.stanza";
-local datamanager = require "util.datamanager";
 local dataform_new = require "util.dataforms".new;
 local usermanager_user_exists = require "core.usermanager".user_exists;
 local usermanager_create_user = require "core.usermanager".create_user;
@@ -22,6 +21,8 @@
 local allow_registration = module:get_option_boolean("allow_registration", false);
 local additional_fields = module:get_option("additional_registration_fields", {});
 
+local account_details = module:open_store("account_details");
+
 local field_map = {
 	username = { name = "username", type = "text-single", label = "Username", required = true };
 	password = { name = "password", type = "text-private", label = "Password", required = true };
@@ -234,7 +235,7 @@
 						-- TODO unable to write file, file may be locked, etc, what's the correct error?
 						local error_reply = st.error_reply(stanza, "wait", "internal-server-error", "Failed to write data to disk.");
 						if usermanager_create_user(username, password, host) then
-							if next(data) and not datamanager.store(username, host, "account_details", data) then
+							if next(data) and not account_details:set(username, data) then
 								usermanager_delete_user(username, host);
 								session.send(error_reply);
 								return true;
--- a/plugins/mod_s2s/mod_s2s.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_s2s/mod_s2s.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -429,7 +429,7 @@
 	end
 end
 
-local function handleerr(err) log("error", "Traceback[s2s]: %s: %s", tostring(err), traceback()); end
+local function handleerr(err) log("error", "Traceback[s2s]: %s", traceback(tostring(err), 2)); end
 function stream_callbacks.handlestanza(session, stanza)
 	if stanza.attr.xmlns == "jabber:client" then --COMPAT: Prosody pre-0.6.2 may send jabber:client
 		stanza.attr.xmlns = nil;
--- a/plugins/mod_vcard.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/mod_vcard.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -8,7 +8,8 @@
 
 local st = require "util.stanza"
 local jid_split = require "util.jid".split;
-local datamanager = require "util.datamanager"
+
+local vcards = module:open_store();
 
 module:add_feature("vcard-temp");
 
@@ -19,9 +20,9 @@
 		local vCard;
 		if to then
 			local node, host = jid_split(to);
-			vCard = st.deserialize(datamanager.load(node, host, "vcard")); -- load vCard for user or server
+			vCard = st.deserialize(vcards:get(node)); -- load vCard for user or server
 		else
-			vCard = st.deserialize(datamanager.load(session.username, session.host, "vcard"));-- load user's own vCard
+			vCard = st.deserialize(vcards:get(session.username));-- load user's own vCard
 		end
 		if vCard then
 			session.send(st.reply(stanza):add_child(vCard)); -- send vCard!
@@ -30,7 +31,7 @@
 		end
 	else
 		if not to then
-			if datamanager.store(session.username, session.host, "vcard", st.preserialize(stanza.tags[1])) then
+			if vcards:set(session.username, st.preserialize(stanza.tags[1])) then
 				session.send(st.reply(stanza));
 			else
 				-- TODO unable to write file, file may be locked, etc, what's the correct error?
--- a/plugins/muc/mod_muc.lua	Fri Apr 19 13:30:37 2013 +0100
+++ b/plugins/muc/mod_muc.lua	Tue Apr 23 15:14:47 2013 +0100
@@ -28,13 +28,14 @@
 local jid_bare = require "util.jid".bare;
 local st = require "util.stanza";
 local uuid_gen = require "util.uuid".generate;
-local datamanager = require "util.datamanager";
 local um_is_admin = require "core.usermanager".is_admin;
 local hosts = prosody.hosts;
 
 rooms = {};
 local rooms = rooms;
-local persistent_rooms = datamanager.load(nil, muc_host, "persistent") or {};
+local persistent_rooms_storage = module:open_store("persistent");
+local persistent_rooms = persistent_rooms_storage:get() or {};
+local room_configs = module:open_store("config");
 
 -- Configurable options
 muclib.set_max_history_length(module:get_option_number("max_history_messages"));
@@ -66,15 +67,15 @@
 			_data = room._data;
 			_affiliations = room._affiliations;
 		};
-		datamanager.store(node, muc_host, "config", data);
+		room_configs:set(node, data);
 		room._data.history = history;
 	elseif forced then
-		datamanager.store(node, muc_host, "config", nil);
+		room_configs:set(node, nil);
 		if not next(room._occupants) then -- Room empty
 			rooms[room.jid] = nil;
 		end
 	end
-	if forced then datamanager.store(nil, muc_host, "persistent", persistent_rooms); end
+	if forced then persistent_rooms_storage:set(nil, persistent_rooms); end
 end
 
 function create_room(jid)
@@ -88,7 +89,7 @@
 local persistent_errors = false;
 for jid in pairs(persistent_rooms) do
 	local node = jid_split(jid);
-	local data = datamanager.load(node, muc_host, "config");
+	local data = room_configs:get(node);
 	if data then
 		local room = create_room(jid);
 		room._data = data._data;
@@ -99,7 +100,7 @@
 		persistent_errors = true;
 	end
 end
-if persistent_errors then datamanager.store(nil, muc_host, "persistent", persistent_rooms); end
+if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end
 
 local host_room = muc_new_room(muc_host);
 host_room.route_stanza = room_route_stanza;