fix: Optimizes hot paths in prosody modules, string comparisons.

This commit is contained in:
damencho 2020-11-05 14:30:06 -06:00 committed by Дамян Минков
parent 0934fffa25
commit 895c92217a
4 changed files with 35 additions and 7 deletions

View File

@ -1,6 +1,8 @@
local jid = require "util.jid"; local jid = require "util.jid";
local um_is_admin = require "core.usermanager".is_admin; local um_is_admin = require "core.usermanager".is_admin;
local is_healthcheck_room = module:require "util".is_healthcheck_room; local util = module:require "util";
local is_healthcheck_room = util.is_healthcheck_room;
local extract_subdomain = util.extract_subdomain;
local moderated_subdomains; local moderated_subdomains;
local moderated_rooms; local moderated_rooms;
@ -22,11 +24,14 @@ end
-- -> true, room_name, subdomain -- -> true, room_name, subdomain
-- -> true, room_name, nil (if no subdomain is used for the room) -- -> true, room_name, nil (if no subdomain is used for the room)
local function is_moderated(room_jid) local function is_moderated(room_jid)
if #moderated_subdomains == 0 and #moderated_rooms == 0 then
return false;
end
local room_node = jid.node(room_jid); local room_node = jid.node(room_jid);
-- parses bare room address, for multidomain expected format is: -- parses bare room address, for multidomain expected format is:
-- [subdomain]roomName@conference.domain -- [subdomain]roomName@conference.domain
local target_subdomain, target_room_name = room_node:match("^%[([^%]]+)%](.+)$"); local target_subdomain, target_room_name = extract_subdomain(room_node);
if target_subdomain then if target_subdomain then
if moderated_subdomains:contains(target_subdomain) then if moderated_subdomains:contains(target_subdomain) then
return true, target_room_name, target_subdomain; return true, target_room_name, target_subdomain;

View File

@ -1,5 +1,6 @@
local ext_events = module:require "ext_events" local ext_events = module:require "ext_events"
local jid = require "util.jid" local jid = require "util.jid"
local extract_subdomain = module:require "util".extract_subdomain;
-- Options and configuration -- Options and configuration
local poltergeist_component = module:get_option_string( local poltergeist_component = module:get_option_string(
@ -33,7 +34,7 @@ local function url_from_room_jid(room_jid)
local node, _, _ = jid.split(room_jid) local node, _, _ = jid.split(room_jid)
if not node then return nil end if not node then return nil end
local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$") local target_subdomain, target_node = extract_subdomain(node);
if not(target_node or target_subdomain) then if not(target_node or target_subdomain) then
return "https://"..muc_domain_base.."/"..node return "https://"..muc_domain_base.."/"..node

View File

@ -9,7 +9,9 @@ local jid = require "util.jid";
local json_safe = require "cjson.safe"; local json_safe = require "cjson.safe";
local path = require "util.paths"; local path = require "util.paths";
local sha256 = require "util.hashes".sha256; local sha256 = require "util.hashes".sha256;
local http_get_with_retry = module:require "util".http_get_with_retry; local main_util = module:require "util";
local http_get_with_retry = main_util.http_get_with_retry;
local extract_subdomain = main_util.extract_subdomain;
local nr_retries = 3; local nr_retries = 3;
@ -350,7 +352,7 @@ function Util:verify_room(session, room_address)
local room_node = jid.node(room_address); local room_node = jid.node(room_address);
-- parses bare room address, for multidomain expected format is: -- parses bare room address, for multidomain expected format is:
-- [subdomain]roomName@conference.domain -- [subdomain]roomName@conference.domain
local target_subdomain, target_room = room_node:match("^%[([^%]]+)%](.+)$"); local target_subdomain, target_room = extract_subdomain(room_node);
-- if we have '*' as room name in token, this means all rooms are allowed -- if we have '*' as room name in token, this means all rooms are allowed
-- so we will use the actual name of the room when constructing strings -- so we will use the actual name of the room when constructing strings

View File

@ -33,6 +33,12 @@ local roomless_iqs = {};
-- (e.g. from room1@conference.foo.example.com/res returns (room1, example.com, res, foo)) -- (e.g. from room1@conference.foo.example.com/res returns (room1, example.com, res, foo))
local function room_jid_split_subdomain(room_jid) local function room_jid_split_subdomain(room_jid)
local node, host, resource = jid.split(room_jid); local node, host, resource = jid.split(room_jid);
-- optimization, skip matching if there is no subdomain or it is not the muc component address at all
if host == muc_domain or not starts_with(host, muc_domain_prefix) then
return node, host, resource;
end
local target_subdomain = host and host:match(target_subdomain_pattern); local target_subdomain = host and host:match(target_subdomain_pattern);
return node, host, resource, target_subdomain return node, host, resource, target_subdomain
end end
@ -80,11 +86,13 @@ local function internal_room_jid_match_rewrite(room_jid, stanza)
return room_jid; return room_jid;
end end
local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$");
local target_subdomain, target_node = extract_subdomain(node);
if not (target_node and target_subdomain) then if not (target_node and target_subdomain) then
-- module:log("debug", "Not rewriting... unexpected node format: %s", node); -- module:log("debug", "Not rewriting... unexpected node format: %s", node);
return room_jid; return room_jid;
end end
-- Ok, rewrite room_jid address to pretty format -- Ok, rewrite room_jid address to pretty format
local new_node, new_host, new_resource = target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource; local new_node, new_host, new_resource = target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource;
room_jid = jid.join(new_node, new_host, new_resource); room_jid = jid.join(new_node, new_host, new_resource);
@ -226,6 +234,17 @@ function is_feature_allowed(session, feature)
end end
end end
--- Extracts the subdomain and room name from internal jid node [foo]room1
-- @return subdomain(optional, if extracted or nil), the room name
function extract_subdomain(room_node)
-- optimization, skip matching if there is no subdomain, no [subdomain] part in the beginning of the node
if not starts_with(room_node, '[') then
return room_node;
end
return room_node:match("^%[([^%]]+)%](.+)$");
end
function starts_with(str, start) function starts_with(str, start)
return str:sub(1, #start) == start return str:sub(1, #start) == start
end end
@ -306,6 +325,7 @@ function http_get_with_retry(url, retry)
end end
return { return {
extract_subdomain = extract_subdomain;
is_feature_allowed = is_feature_allowed; is_feature_allowed = is_feature_allowed;
is_healthcheck_room = is_healthcheck_room; is_healthcheck_room = is_healthcheck_room;
get_room_from_jid = get_room_from_jid; get_room_from_jid = get_room_from_jid;