fix: Prosody modules - drop unused and duplicate code and drop chatty debug statements (#8027)
* chore: Updates mod_smacks.lua version to latest. https://hg.prosody.im/prosody-modules/file/db75772afb28/mod_smacks/mod_smacks.lua * Drop unused modules. * Update docs. * Move utility functions away from domain mapper. * Remove some chatty debug log messages. * Drops not needed patch for mod_websocket.
This commit is contained in:
parent
a242e86b23
commit
9f65ae52f1
|
@ -1,5 +0,0 @@
|
|||
local jibri_queue_component
|
||||
= module:get_option_string(
|
||||
"jibri_queue_component", "jibriqueue"..module.host);
|
||||
|
||||
module:add_identity("component", "jibri-queue", jibri_queue_component);
|
|
@ -1,559 +0,0 @@
|
|||
local st = require "util.stanza";
|
||||
local jid = require "util.jid";
|
||||
local http = require "net.http";
|
||||
local json = require "cjson";
|
||||
local inspect = require('inspect');
|
||||
local socket = require "socket";
|
||||
local uuid_gen = require "util.uuid".generate;
|
||||
local jwt = require "luajwtjitsi";
|
||||
local it = require "util.iterators";
|
||||
local neturl = require "net.url";
|
||||
local parse = neturl.parseQuery;
|
||||
|
||||
local get_room_from_jid = module:require "util".get_room_from_jid;
|
||||
local room_jid_match_rewrite = module:require "util".room_jid_match_rewrite;
|
||||
local is_healthcheck_room = module:require "util".is_healthcheck_room;
|
||||
local room_jid_split_subdomain = module:require "util".room_jid_split_subdomain;
|
||||
local internal_room_jid_match_rewrite = module:require "util".internal_room_jid_match_rewrite;
|
||||
local async_handler_wrapper = module:require "util".async_handler_wrapper;
|
||||
|
||||
-- this basically strips the domain from the conference.domain address
|
||||
local parentHostName = string.gmatch(tostring(module.host), "%w+.(%w.+)")();
|
||||
if parentHostName == nil then
|
||||
log("error", "Failed to start - unable to get parent hostname");
|
||||
return;
|
||||
end
|
||||
|
||||
local parentCtx = module:context(parentHostName);
|
||||
if parentCtx == nil then
|
||||
log("error",
|
||||
"Failed to start - unable to get parent context for host: %s",
|
||||
tostring(parentHostName));
|
||||
return;
|
||||
end
|
||||
local token_util = module:require "token/util".new(parentCtx);
|
||||
|
||||
local ASAPKeyServer;
|
||||
local ASAPKeyPath;
|
||||
local ASAPKeyId;
|
||||
local ASAPIssuer;
|
||||
local ASAPAudience;
|
||||
local ASAPAcceptedIssuers;
|
||||
local ASAPAcceptedAudiences;
|
||||
local ASAPTTL;
|
||||
local ASAPTTL_THRESHOLD;
|
||||
local ASAPKey;
|
||||
local JibriRegion;
|
||||
local disableTokenVerification;
|
||||
local muc_component_host;
|
||||
local external_api_url;
|
||||
local jwtKeyCacheSize;
|
||||
local jwtKeyCache;
|
||||
|
||||
local function load_config()
|
||||
ASAPKeyServer = module:get_option_string("asap_key_server");
|
||||
|
||||
if ASAPKeyServer then
|
||||
module:log("debug", "ASAP Public Key URL %s", ASAPKeyServer);
|
||||
token_util:set_asap_key_server(ASAPKeyServer);
|
||||
end
|
||||
|
||||
ASAPKeyPath
|
||||
= module:get_option_string("asap_key_path", '/etc/prosody/certs/asap.key');
|
||||
|
||||
ASAPKeyId
|
||||
= module:get_option_string("asap_key_id", 'jitsi');
|
||||
|
||||
ASAPIssuer
|
||||
= module:get_option_string("asap_issuer", 'jitsi');
|
||||
|
||||
ASAPAudience
|
||||
= module:get_option_string("asap_audience", 'jibri-queue');
|
||||
|
||||
ASAPAcceptedIssuers
|
||||
= module:get_option_array('asap_accepted_issuers',{'jibri-queue'});
|
||||
module:log("debug", "ASAP Accepted Issuers %s", ASAPAcceptedIssuers);
|
||||
token_util:set_asap_accepted_issuers(ASAPAcceptedIssuers);
|
||||
|
||||
ASAPAcceptedAudiences
|
||||
= module:get_option_array('asap_accepted_audiences',{'*'});
|
||||
module:log("debug", "ASAP Accepted Audiences %s", ASAPAcceptedAudiences);
|
||||
token_util:set_asap_accepted_audiences(ASAPAcceptedAudiences);
|
||||
|
||||
-- do not require room to be set on tokens for jibri queue
|
||||
token_util:set_asap_require_room_claim(false);
|
||||
|
||||
ASAPTTL
|
||||
= module:get_option_number("asap_ttl", 3600);
|
||||
|
||||
ASAPTTL_THRESHOLD
|
||||
= module:get_option_number("asap_ttl_threshold", 600);
|
||||
|
||||
queueServiceURL
|
||||
= module:get_option_string("jibri_queue_url");
|
||||
|
||||
JibriRegion
|
||||
= module:get_option_string("jibri_region", 'default');
|
||||
|
||||
-- option to enable/disable token verifications
|
||||
disableTokenVerification
|
||||
= module:get_option_boolean("disable_jibri_queue_token_verification", false);
|
||||
|
||||
muc_component_host
|
||||
= module:get_option_string("muc_component");
|
||||
|
||||
external_api_url = module:get_option_string("external_api_url",tostring(parentHostName));
|
||||
module:log("debug", "External advertised API URL", external_api_url);
|
||||
|
||||
|
||||
-- TODO: Figure out a less arbitrary default cache size.
|
||||
jwtKeyCacheSize
|
||||
= module:get_option_number("jwt_pubkey_cache_size", 128);
|
||||
jwtKeyCache = require"util.cache".new(jwtKeyCacheSize);
|
||||
|
||||
if queueServiceURL == nil then
|
||||
log("error", "No jibri_queue_url specified. No service to contact!");
|
||||
return;
|
||||
end
|
||||
|
||||
if muc_component_host == nil then
|
||||
log("error", "No muc_component specified. No muc to operate on for jibri queue!");
|
||||
return;
|
||||
end
|
||||
|
||||
-- Read ASAP key once on module startup
|
||||
local f = io.open(ASAPKeyPath, "r");
|
||||
if f then
|
||||
ASAPKey = f:read("*all");
|
||||
f:close();
|
||||
if not ASAPKey then
|
||||
module:log("warn", "No ASAP Key read from %s, disabling jibri queue component plugin", ASAPKeyPath);
|
||||
return
|
||||
end
|
||||
else
|
||||
module:log("warn", "Error reading ASAP Key %s, disabling jibri queue component plugin", ASAPKeyPath);
|
||||
return
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
local function reload_config()
|
||||
module:log("info", "Reloading configuration for jibri queue component");
|
||||
local config_success = load_config();
|
||||
|
||||
-- clear ASAP public key cache on config reload
|
||||
token_util:clear_asap_cache();
|
||||
|
||||
if not config_success then
|
||||
log("error", "Unsuccessful reconfiguration, jibri queue component may misbehave");
|
||||
end
|
||||
end
|
||||
|
||||
local config_success = load_config();
|
||||
|
||||
if not config_success then
|
||||
log("error", "Unsuccessful configuration step, jibri queue component disabled")
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
local http_headers = {
|
||||
["User-Agent"] = "Prosody ("..prosody.version.."; "..prosody.platform..")",
|
||||
["Content-Type"] = "application/json"
|
||||
};
|
||||
|
||||
-- we use async to detect Prosody 0.10 and earlier
|
||||
local have_async = pcall(require, "util.async");
|
||||
if not have_async then
|
||||
module:log("warn", "conference duration will not work with Prosody version 0.10 or less.");
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
log("info", "Starting jibri queue handling for %s", muc_component_host);
|
||||
|
||||
local function round(num, numDecimalPlaces)
|
||||
local mult = 10^(numDecimalPlaces or 0)
|
||||
return math.floor(num * mult + 0.5) / mult
|
||||
end
|
||||
|
||||
local function generateToken(audience)
|
||||
audience = audience or ASAPAudience
|
||||
local t = os.time()
|
||||
local err
|
||||
local exp_key = 'asap_exp.'..audience
|
||||
local token_key = 'asap_token.'..audience
|
||||
local exp = jwtKeyCache:get(exp_key)
|
||||
local token = jwtKeyCache:get(token_key)
|
||||
|
||||
--if we find a token and it isn't too far from expiry, then use it
|
||||
if token ~= nil and exp ~= nil then
|
||||
exp = tonumber(exp)
|
||||
if (exp - t) > ASAPTTL_THRESHOLD then
|
||||
return token
|
||||
end
|
||||
end
|
||||
|
||||
--expiry is the current time plus TTL
|
||||
exp = t + ASAPTTL
|
||||
local payload = {
|
||||
iss = ASAPIssuer,
|
||||
aud = audience,
|
||||
nbf = t,
|
||||
exp = exp,
|
||||
}
|
||||
|
||||
-- encode
|
||||
local alg = "RS256"
|
||||
token, err = jwt.encode(payload, ASAPKey, alg, {kid = ASAPKeyId})
|
||||
if not err then
|
||||
token = 'Bearer '..token
|
||||
jwtKeyCache:set(exp_key,exp)
|
||||
jwtKeyCache:set(token_key,token)
|
||||
return token
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
local function sendIq(participant,action,requestId,time,position,token)
|
||||
local iqId = uuid_gen();
|
||||
local from = module:get_host();
|
||||
local outStanza = st.iq({type = 'set', from = from, to = participant, id = iqId}):tag("jibri-queue",
|
||||
{ xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId, action = action });
|
||||
|
||||
if token then
|
||||
outStanza:tag("token"):text(token):up()
|
||||
end
|
||||
if time then
|
||||
outStanza:tag("time"):text(tostring(time)):up()
|
||||
end
|
||||
if position then
|
||||
outStanza:tag("position"):text(tostring(position)):up()
|
||||
end
|
||||
|
||||
module:send(outStanza);
|
||||
end
|
||||
|
||||
local function cb(content_, code_, response_, request_)
|
||||
if code_ == 200 or code_ == 204 then
|
||||
module:log("debug", "URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s",
|
||||
code_, content_, request_.host, request_.path, inspect(request_.body), inspect(response_));
|
||||
else
|
||||
module:log("warn", "URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s",
|
||||
code_, content_, inspect(request_), inspect(response_));
|
||||
end
|
||||
end
|
||||
|
||||
local function sendEvent(type,room_address,participant,requestId,replyIq,replyError)
|
||||
local event_ts = round(socket.gettime()*1000);
|
||||
local node, host, resource, target_subdomain = room_jid_split_subdomain(room_address);
|
||||
local room_param = '';
|
||||
if target_subdomain then
|
||||
room_param = target_subdomain..'/'..node;
|
||||
else
|
||||
room_param = node;
|
||||
end
|
||||
|
||||
local out_event = {
|
||||
["conference"] = room_address,
|
||||
["roomParam"] = room_param,
|
||||
["eventType"] = type,
|
||||
["participant"] = participant,
|
||||
["externalApiUrl"] = external_api_url.."/jibriqueue/update",
|
||||
["requestId"] = requestId,
|
||||
["region"] = JibriRegion,
|
||||
}
|
||||
module:log("debug","Sending event %s",inspect(out_event));
|
||||
|
||||
local headers = http_headers or {}
|
||||
headers['Authorization'] = generateToken()
|
||||
|
||||
module:log("debug","Sending headers %s",inspect(headers));
|
||||
local requestURL = queueServiceURL.."/job/recording"
|
||||
if type=="LeaveQueue" then
|
||||
requestURL = requestURL .."/cancel"
|
||||
end
|
||||
local request = http.request(requestURL, {
|
||||
headers = headers,
|
||||
method = "POST",
|
||||
body = json.encode(out_event)
|
||||
}, function (content_, code_, response_, request_)
|
||||
if code_ == 200 or code_ == 204 then
|
||||
module:log("debug", "URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s",
|
||||
code_, content_, request_.host, request_.path, inspect(request_.body), inspect(response_));
|
||||
if (replyIq) then
|
||||
module:log("debug", "sending reply IQ %s",inspect(replyIq));
|
||||
module:send(replyIq);
|
||||
end
|
||||
else
|
||||
module:log("warn", "URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s",
|
||||
code_, content_, inspect(request_), inspect(response_));
|
||||
if (replyError) then
|
||||
module:log("warn", "sending reply error IQ %s",inspect(replyError));
|
||||
module:send(replyError);
|
||||
end
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
function clearRoomQueueByOccupant(room, occupant)
|
||||
room.jibriQueue[occupant.jid] = nil;
|
||||
end
|
||||
|
||||
function addRoomQueueByOccupant(room, occupant, requestId)
|
||||
room.jibriQueue[occupant.jid] = requestId;
|
||||
end
|
||||
|
||||
-- receives iq from client currently connected to the room
|
||||
function on_iq(event)
|
||||
local requestId;
|
||||
-- Check the type of the incoming stanza to avoid loops:
|
||||
if event.stanza.attr.type == "error" then
|
||||
return; -- We do not want to reply to these, so leave.
|
||||
end
|
||||
if event.stanza.attr.to == module:get_host() then
|
||||
if event.stanza.attr.type == "set" then
|
||||
local reply = st.reply(event.stanza);
|
||||
local replyError = st.error_reply(event.stanza,'cancel','internal-server-error',"Queue Server Error");
|
||||
|
||||
local jibriQueue
|
||||
= event.stanza:get_child('jibri-queue', 'http://jitsi.org/protocol/jibri-queue');
|
||||
if jibriQueue then
|
||||
module:log("debug", "Received Jibri Queue Request: %s ",inspect(jibriQueue));
|
||||
|
||||
local roomAddress = jibriQueue.attr.room;
|
||||
local room = get_room_from_jid(room_jid_match_rewrite(roomAddress));
|
||||
|
||||
if not room then
|
||||
module:log("warn", "No room found %s", roomAddress);
|
||||
return false;
|
||||
end
|
||||
|
||||
local from = event.stanza.attr.from;
|
||||
|
||||
local occupant = room:get_occupant_by_real_jid(from);
|
||||
if not occupant then
|
||||
module:log("warn", "No occupant %s found for %s", from, roomAddress);
|
||||
return false;
|
||||
end
|
||||
|
||||
local action = jibriQueue.attr.action;
|
||||
if action == 'join' then
|
||||
-- join action, so send event out
|
||||
requestId = uuid_gen();
|
||||
module:log("debug","Received join queue request for jid %s occupant %s requestId %s",roomAddress,occupant.jid,requestId);
|
||||
|
||||
-- now handle new jibri queue message
|
||||
addRoomQueueByOccupant(room, occupant, requestId);
|
||||
reply:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
||||
replyError:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
||||
|
||||
module:log("debug","Sending JoinQueue event for jid %s occupant %s reply %s",roomAddress,occupant.jid,inspect(reply));
|
||||
sendEvent('JoinQueue',roomAddress,occupant.jid,requestId,reply,replyError);
|
||||
end
|
||||
if action == 'leave' then
|
||||
requestId = jibriQueue.attr.requestId;
|
||||
module:log("debug","Received leave queue request for jid %s occupant %s requestId %s",roomAddress,occupant.jid,requestId);
|
||||
|
||||
-- TODO: check that requestId is the same as cached value
|
||||
clearRoomQueueByOccupant(room, occupant);
|
||||
reply:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
||||
replyError:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
||||
|
||||
module:log("debug","Sending LeaveQueue event for jid %s occupant %s reply %s",roomAddress,occupant.jid,inspect(reply));
|
||||
sendEvent('LeaveQueue',roomAddress,occupant.jid,requestId,reply,replyError);
|
||||
end
|
||||
else
|
||||
module:log("warn","Jibri Queue Stanza missing child %s",inspect(event.stanza))
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- create recorder queue cache for the room
|
||||
function room_created(event)
|
||||
local room = event.room;
|
||||
|
||||
if is_healthcheck_room(room.jid) then
|
||||
return;
|
||||
end
|
||||
|
||||
room.jibriQueue = {};
|
||||
end
|
||||
|
||||
-- Conference ended, clear all queue cache jids
|
||||
function room_destroyed(event)
|
||||
local room = event.room;
|
||||
|
||||
if is_healthcheck_room(room.jid) then
|
||||
return;
|
||||
end
|
||||
for jid, x in pairs(room.jibriQueue) do
|
||||
if x then
|
||||
sendEvent('LeaveQueue',internal_room_jid_match_rewrite(room.jid),jid,x);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Occupant left remove it from the queue if it joined the queue
|
||||
function occupant_leaving(event)
|
||||
local room = event.room;
|
||||
|
||||
if is_healthcheck_room(room.jid) then
|
||||
return;
|
||||
end
|
||||
|
||||
local occupant = event.occupant;
|
||||
local requestId = room.jibriQueue[occupant.jid];
|
||||
-- check if user has cached queue request
|
||||
if requestId then
|
||||
-- remove occupant from queue cache, signal backend
|
||||
room.jibriQueue[occupant.jid] = nil;
|
||||
sendEvent('LeaveQueue',internal_room_jid_match_rewrite(room.jid),occupant.jid,requestId);
|
||||
end
|
||||
end
|
||||
|
||||
module:hook("iq/host", on_iq);
|
||||
|
||||
-- executed on every host added internally in prosody, including components
|
||||
function process_host(host)
|
||||
if host == muc_component_host then -- the conference muc component
|
||||
module:log("debug","Hook to muc events on %s", host);
|
||||
|
||||
local muc_module = module:context(host);
|
||||
muc_module:hook("muc-room-created", room_created, -1);
|
||||
-- muc_module:hook("muc-occupant-joined", occupant_joined, -1);
|
||||
muc_module:hook("muc-occupant-pre-leave", occupant_leaving, -1);
|
||||
muc_module:hook("muc-room-destroyed", room_destroyed, -1);
|
||||
end
|
||||
end
|
||||
|
||||
if prosody.hosts[muc_component_host] == nil then
|
||||
module:log("debug","No muc component found, will listen for it: %s", muc_component_host)
|
||||
|
||||
-- when a host or component is added
|
||||
prosody.events.add_handler("host-activated", process_host);
|
||||
else
|
||||
process_host(muc_component_host);
|
||||
end
|
||||
|
||||
module:log("info", "Loading jibri_queue_component");
|
||||
|
||||
--- Verifies room name, domain name with the values in the token
|
||||
-- @param token the token we received
|
||||
-- @param room_name the room name
|
||||
-- @param group name of the group (optional)
|
||||
-- @param session the session to use for storing token specific fields
|
||||
-- @return true if values are ok or false otherwise
|
||||
function verify_token(token, room_jid, session)
|
||||
if disableTokenVerification then
|
||||
return true;
|
||||
end
|
||||
|
||||
-- if not disableTokenVerification and we do not have token
|
||||
-- stop here, cause the main virtual host can have guest access enabled
|
||||
-- (allowEmptyToken = true) and we will allow access to rooms info without
|
||||
-- a token
|
||||
if token == nil then
|
||||
log("warn", "no token provided");
|
||||
return false;
|
||||
end
|
||||
|
||||
session.auth_token = token;
|
||||
local verified, reason, message = token_util:process_and_verify_token(session);
|
||||
if not verified then
|
||||
log("warn", "not a valid token %s: %s", tostring(reason), tostring(message));
|
||||
log("debug", "invalid token %s", token);
|
||||
return false;
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
|
||||
--- Handles request for updating jibri queue status
|
||||
-- @param event the http event, holds the request query
|
||||
-- @return GET response, containing a json with response details
|
||||
function handle_update_jibri_queue(event)
|
||||
local body = json.decode(event.request.body);
|
||||
|
||||
module:log("debug","Update Jibri Queue Event Received: %s",inspect(body));
|
||||
|
||||
local token = event.request.headers["authorization"];
|
||||
if not token then
|
||||
token = ''
|
||||
else
|
||||
local prefixStart, prefixEnd = token:find("Bearer ");
|
||||
if prefixStart ~= 1 then
|
||||
module:log("error", "REST event: Invalid authorization header format. The header must start with the string 'Bearer '");
|
||||
return { status_code = 403; };
|
||||
end
|
||||
token = token:sub(prefixEnd + 1);
|
||||
end
|
||||
|
||||
local user_jid = body["participant"];
|
||||
local roomAddress = body["conference"];
|
||||
local userJWT = body["token"];
|
||||
local action = body["action"];
|
||||
local time = body["time"];
|
||||
local position = body["position"];
|
||||
local requestId = body["requestId"];
|
||||
|
||||
if not action then
|
||||
if userJWT then
|
||||
action = 'token';
|
||||
else
|
||||
action = 'info';
|
||||
end
|
||||
end
|
||||
|
||||
local room_jid = room_jid_match_rewrite(roomAddress);
|
||||
|
||||
if not verify_token(token, room_jid, {}) then
|
||||
log("error", "REST event: Invalid token for room %s to route action %s for requestId %s", roomAddress, action, requestId);
|
||||
return { status_code = 403; };
|
||||
end
|
||||
|
||||
local room = get_room_from_jid(room_jid);
|
||||
if (not room) then
|
||||
log("error", "REST event: no room found %s to route action %s for requestId %s", roomAddress, action, requestId);
|
||||
return { status_code = 404; };
|
||||
end
|
||||
|
||||
local occupant = room:get_occupant_by_real_jid(user_jid);
|
||||
if not occupant then
|
||||
log("warn", "REST event: No occupant %s found for %s to route action %s for requestId %s", user_jid, roomAddress, action, requestId);
|
||||
return { status_code = 404; };
|
||||
end
|
||||
|
||||
if not room.jibriQueue[occupant.jid] then
|
||||
log("warn", "REST event: No queue request found for occupant %s in conference %s to route action %s for requestId %s",occupant.jid,room.jid, action, requestId)
|
||||
return { status_code = 404; };
|
||||
end
|
||||
|
||||
if not requestId then
|
||||
requestId = room.jibriQueue[occupant.jid];
|
||||
end
|
||||
|
||||
if action == 'token' and userJWT then
|
||||
log("debug", "REST event: Token received for occupant %s in conference %s requestId %s, clearing room queue");
|
||||
clearRoomQueueByOccupant(room, occupant);
|
||||
end
|
||||
|
||||
log("debug", "REST event: Sending update for occupant %s in conference %s to route action %s for requestId %s",occupant.jid,room.jid, action, requestId);
|
||||
sendIq(occupant.jid,action,requestId,time,position,userJWT);
|
||||
return { status_code = 200; };
|
||||
end
|
||||
|
||||
module:depends("http");
|
||||
module:provides("http", {
|
||||
default_path = "/";
|
||||
name = "jibriqueue";
|
||||
route = {
|
||||
["POST /jibriqueue/update"] = function (event) return async_handler_wrapper(event,handle_update_jibri_queue) end;
|
||||
};
|
||||
});
|
||||
|
||||
module:hook_global('config-reloaded', reload_config);
|
|
@ -7,99 +7,32 @@ local jid = require "util.jid";
|
|||
|
||||
local filters = require "util.filters";
|
||||
|
||||
local muc_domain_prefix = module:get_option_string("muc_mapper_domain_prefix", "conference");
|
||||
|
||||
local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
|
||||
if not muc_domain_base then
|
||||
module:log("warn", "No 'muc_mapper_domain_base' option set, disabling muc_mapper plugin inactive");
|
||||
return
|
||||
end
|
||||
|
||||
-- The "real" MUC domain that we are proxying to
|
||||
local muc_domain = module:get_option_string("muc_mapper_domain", muc_domain_prefix.."."..muc_domain_base);
|
||||
|
||||
local escaped_muc_domain_base = muc_domain_base:gsub("%p", "%%%1");
|
||||
local escaped_muc_domain_prefix = muc_domain_prefix:gsub("%p", "%%%1");
|
||||
-- The pattern used to extract the target subdomain (e.g. extract 'foo' from 'foo.muc.example.com')
|
||||
local target_subdomain_pattern = "^"..escaped_muc_domain_prefix..".([^%.]+)%."..escaped_muc_domain_base;
|
||||
|
||||
-- table to store all incoming iqs without roomname in it, like discoinfo to the muc compoent
|
||||
local roomless_iqs = {};
|
||||
|
||||
if not muc_domain then
|
||||
module:log("warn", "No 'muc_mapper_domain' option set, disabling muc_mapper plugin inactive");
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Utility function to check and convert a room JID from virtual room1@muc.foo.example.com to real [foo]room1@muc.example.com
|
||||
local function match_rewrite_to_jid(room_jid, stanza)
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
local target_subdomain = host and host:match(target_subdomain_pattern);
|
||||
if not target_subdomain then
|
||||
module:log("debug", "No need to rewrite out 'to' %s", room_jid);
|
||||
return room_jid;
|
||||
end
|
||||
-- Ok, rewrite room_jid address to new format
|
||||
local new_node, new_host, new_resource;
|
||||
if node then
|
||||
new_node, new_host, new_resource = "["..target_subdomain.."]"..node, muc_domain, resource;
|
||||
else
|
||||
module:log("debug", "No room name provided so rewriting only host 'to' %s", room_jid);
|
||||
new_host, new_resource = muc_domain, resource;
|
||||
|
||||
if (stanza.attr and stanza.attr.id) then
|
||||
roomless_iqs[stanza.attr.id] = stanza.attr.to;
|
||||
end
|
||||
end
|
||||
room_jid = jid.join(new_node, new_host, new_resource);
|
||||
module:log("debug", "Rewrote to %s", room_jid);
|
||||
return room_jid
|
||||
end
|
||||
|
||||
-- Utility function to check and convert a room JID from real [foo]room1@muc.example.com to virtual room1@muc.foo.example.com
|
||||
local function match_rewrite_from_jid(room_jid, stanza)
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
if host ~= muc_domain or not node then
|
||||
module:log("debug", "No need to rewrite %s (not from the MUC host) %s, %s", room_jid, stanza.attr.id, roomless_iqs[stanza.attr.id]);
|
||||
|
||||
if (stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
|
||||
local result = roomless_iqs[stanza.attr.id];
|
||||
roomless_iqs[stanza.attr.id] = nil;
|
||||
return result;
|
||||
end
|
||||
|
||||
return room_jid;
|
||||
end
|
||||
local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$");
|
||||
if not (target_node and target_subdomain) then
|
||||
module:log("debug", "Not rewriting... unexpected node format: %s", node);
|
||||
return room_jid;
|
||||
end
|
||||
-- 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;
|
||||
room_jid = jid.join(new_node, new_host, new_resource);
|
||||
module:log("debug", "Rewrote to %s", room_jid);
|
||||
return room_jid
|
||||
end
|
||||
|
||||
local util = module:require "util";
|
||||
local room_jid_match_rewrite = util.room_jid_match_rewrite;
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
|
||||
-- We must filter stanzas in order to hook in to all incoming and outgoing messaging which skips the stanza routers
|
||||
function filter_stanza(stanza)
|
||||
if stanza.name == "message" or stanza.name == "iq" or stanza.name == "presence" then
|
||||
module:log("debug", "Filtering stanza type %s to %s from %s",stanza.name,stanza.attr.to,stanza.attr.from);
|
||||
-- module:log("debug", "Filtering stanza type %s to %s from %s",stanza.name,stanza.attr.to,stanza.attr.from);
|
||||
if stanza.name == "iq" then
|
||||
local conf = stanza:get_child('conference')
|
||||
if conf then
|
||||
module:log("debug", "Filtering stanza conference %s to %s from %s",conf.attr.room,stanza.attr.to,stanza.attr.from);
|
||||
conf.attr.room = match_rewrite_to_jid(conf.attr.room, stanza)
|
||||
-- module:log("debug", "Filtering stanza conference %s to %s from %s",conf.attr.room,stanza.attr.to,stanza.attr.from);
|
||||
conf.attr.room = room_jid_match_rewrite(conf.attr.room, stanza)
|
||||
end
|
||||
end
|
||||
if stanza.attr.to then
|
||||
stanza.attr.to = match_rewrite_to_jid(stanza.attr.to, stanza)
|
||||
stanza.attr.to = room_jid_match_rewrite(stanza.attr.to, stanza)
|
||||
end
|
||||
if stanza.attr.from then
|
||||
stanza.attr.from = match_rewrite_from_jid(stanza.attr.from, stanza)
|
||||
stanza.attr.from = internal_room_jid_match_rewrite(stanza.attr.from, stanza)
|
||||
end
|
||||
end
|
||||
return stanza;
|
||||
|
@ -107,7 +40,6 @@ end
|
|||
|
||||
function filter_session(session)
|
||||
module:log("warn", "Session filters applied");
|
||||
-- filters.add_filter(session, "stanzas/in", filter_stanza_in);
|
||||
filters.add_filter(session, "stanzas/out", filter_stanza);
|
||||
end
|
||||
|
||||
|
@ -128,14 +60,14 @@ end
|
|||
local function outgoing_stanza_rewriter(event)
|
||||
local stanza = event.stanza;
|
||||
if stanza.attr.to then
|
||||
stanza.attr.to = match_rewrite_to_jid(stanza.attr.to, stanza)
|
||||
stanza.attr.to = room_jid_match_rewrite(stanza.attr.to, stanza)
|
||||
end
|
||||
end
|
||||
|
||||
local function incoming_stanza_rewriter(event)
|
||||
local stanza = event.stanza;
|
||||
if stanza.attr.from then
|
||||
stanza.attr.from = match_rewrite_from_jid(stanza.attr.from, stanza)
|
||||
stanza.attr.from = internal_room_jid_match_rewrite(stanza.attr.from, stanza)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ local cache = dep.softreq("util.cache"); -- only available in prosody 0.10+
|
|||
local uuid_generate = require "util.uuid".generate;
|
||||
local jid = require "util.jid";
|
||||
|
||||
local t_insert, t_remove = table.insert, table.remove;
|
||||
local t_remove = table.remove;
|
||||
local math_min = math.min;
|
||||
local math_max = math.max;
|
||||
local os_time = os.time;
|
||||
|
@ -26,6 +26,7 @@ local add_filter = require "util.filters".add_filter;
|
|||
local timer = require "util.timer";
|
||||
local datetime = require "util.datetime";
|
||||
|
||||
local xmlns_mam2 = "urn:xmpp:mam:2";
|
||||
local xmlns_sm2 = "urn:xmpp:sm:2";
|
||||
local xmlns_sm3 = "urn:xmpp:sm:3";
|
||||
local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas";
|
||||
|
@ -34,11 +35,11 @@ local xmlns_delay = "urn:xmpp:delay";
|
|||
local sm2_attr = { xmlns = xmlns_sm2 };
|
||||
local sm3_attr = { xmlns = xmlns_sm3 };
|
||||
|
||||
local resume_timeout = module:get_option_number("smacks_hibernation_time", 300);
|
||||
local resume_timeout = module:get_option_number("smacks_hibernation_time", 600);
|
||||
local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", false);
|
||||
local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false);
|
||||
local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0);
|
||||
local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 60);
|
||||
local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30);
|
||||
local max_hibernated_sessions = module:get_option_number("smacks_max_hibernated_sessions", 10);
|
||||
local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10);
|
||||
local core_process_stanza = prosody.core_process_stanza;
|
||||
|
@ -200,8 +201,15 @@ local function request_ack_if_needed(session, force, reason)
|
|||
end
|
||||
|
||||
local function outgoing_stanza_filter(stanza, session)
|
||||
local is_stanza = stanza.attr and not stanza.attr.xmlns and not stanza.name:find":";
|
||||
if is_stanza and not stanza._cached then -- Stanza in default stream namespace
|
||||
-- XXX: Normally you wouldn't have to check the xmlns for a stanza as it's
|
||||
-- supposed to be nil.
|
||||
-- However, when using mod_smacks with mod_websocket, then mod_websocket's
|
||||
-- stanzas/out filter can get called before this one and adds the xmlns.
|
||||
local is_stanza = stanza.attr and
|
||||
(not stanza.attr.xmlns or stanza.attr.xmlns == 'jabber:client')
|
||||
and not stanza.name:find":";
|
||||
|
||||
if is_stanza and not stanza._cached then
|
||||
local queue = session.outgoing_stanza_queue;
|
||||
local cached_stanza = st.clone(stanza);
|
||||
cached_stanza._cached = true;
|
||||
|
@ -400,6 +408,7 @@ local function handle_unacked_stanzas(session)
|
|||
session.outgoing_stanza_queue = {};
|
||||
for i=1,#queue do
|
||||
if not module:fire_event("delivery/failure", { session = session, stanza = queue[i] }) then
|
||||
if queue[i].attr.type ~= "error" then
|
||||
local reply = st.reply(queue[i]);
|
||||
if reply.attr.to ~= session.full_jid then
|
||||
reply.attr.type = "error";
|
||||
|
@ -410,40 +419,50 @@ local function handle_unacked_stanzas(session)
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- don't send delivery errors for messages which will be delivered by mam later on
|
||||
-- check if stanza was archived --> this will allow us to send back errors for stanzas not archived
|
||||
-- because the user configured the server to do so ("no-archive"-setting for one special contact for example)
|
||||
local function get_stanza_id(stanza, by_jid)
|
||||
for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do
|
||||
if tag.attr.by == by_jid then
|
||||
return tag.attr.id;
|
||||
end
|
||||
end
|
||||
return nil;
|
||||
end
|
||||
module:hook("delivery/failure", function(event)
|
||||
local session, stanza = event.session, event.stanza;
|
||||
-- Only deal with authenticated (c2s) sessions
|
||||
if session.username then
|
||||
if stanza.name == "message" and stanza.attr.xmlns == nil and
|
||||
( stanza.attr.type == "chat" or ( stanza.attr.type or "normal" ) == "normal" ) then
|
||||
-- don't store messages in offline store if they are mam results
|
||||
local mam_result = stanza:get_child("result", xmlns_mam2);
|
||||
if mam_result ~= nil then
|
||||
return true; -- stanza already "handled", don't send an error and don't add it to offline storage
|
||||
end
|
||||
-- do nothing here for normal messages and don't send out "message delivery errors",
|
||||
-- because messages are already in MAM at this point (no need to frighten users)
|
||||
if session.mam_requested and stanza._was_archived then
|
||||
local stanza_id = get_stanza_id(stanza, jid.bare(session.full_jid));
|
||||
if session.mam_requested and stanza_id ~= nil then
|
||||
session.log("debug", "mod_smacks delivery/failure returning true for mam-handled stanza: mam-archive-id=%s", tostring(stanza_id));
|
||||
return true; -- stanza handled, don't send an error
|
||||
end
|
||||
-- store message in offline store, if this client does not use mam *and* was the last client online
|
||||
local sessions = prosody.hosts[module.host].sessions[session.username] and
|
||||
prosody.hosts[module.host].sessions[session.username].sessions or nil;
|
||||
if sessions and next(sessions) == session.resource and next(sessions, session.resource) == nil then
|
||||
module:fire_event("message/offline/handle", { origin = session, stanza = stanza } );
|
||||
return true; -- stanza handled, don't send an error
|
||||
local ok = module:fire_event("message/offline/handle", { origin = session, stanza = stanza } );
|
||||
session.log("debug", "mod_smacks delivery/failuere returning %s for offline-handled stanza", tostring(ok));
|
||||
return ok; -- if stanza was handled, don't send an error
|
||||
end
|
||||
end
|
||||
end
|
||||
end);
|
||||
|
||||
-- mark stanzas as archived --> this will allow us to send back errors for stanzas not archived
|
||||
-- because the user configured the server to do so ("no-archive"-setting for one special contact for example)
|
||||
module:hook("archive-message-added", function(event)
|
||||
local session, stanza, for_user, stanza_id = event.origin, event.stanza, event.for_user, event.id;
|
||||
if session then session.log("debug", "Marking stanza as archived, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end
|
||||
if not session then module:log("debug", "Marking stanza as archived in unknown session, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end
|
||||
stanza._was_archived = true;
|
||||
end);
|
||||
|
||||
module:hook("pre-resource-unbind", function (event)
|
||||
local session, err = event.session, event.error;
|
||||
if session.smacks then
|
||||
|
|
|
@ -93,8 +93,7 @@ end
|
|||
-- saves start time if it is new dominat speaker
|
||||
-- or calculates and accumulates time of speaking
|
||||
function SpeakerStats:setDominantSpeaker(isNowDominantSpeaker)
|
||||
log("debug",
|
||||
"set isDominant %s for %s", tostring(isNowDominantSpeaker), self.nick);
|
||||
-- log("debug", "set isDominant %s for %s", tostring(isNowDominantSpeaker), self.nick);
|
||||
|
||||
if not self:isDominantSpeaker() and isNowDominantSpeaker then
|
||||
self._dominantSpeakerStart = socket.gettime()*1000;
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
--- mod_websocket.lua
|
||||
+++ mod_websocket.lua
|
||||
@@ -163,34 +163,34 @@ function handle_request(event)
|
||||
return 403;
|
||||
end
|
||||
|
||||
- local function websocket_close(code, message)
|
||||
+ local function websocket_close(conn, code, message)
|
||||
conn:write(build_close(code, message));
|
||||
conn:close();
|
||||
end
|
||||
|
||||
local dataBuffer;
|
||||
- local function handle_frame(frame)
|
||||
+ local function handle_frame(conn, frame)
|
||||
local opcode = frame.opcode;
|
||||
local length = frame.length;
|
||||
module:log("debug", "Websocket received frame: opcode=%0x, %i bytes", frame.opcode, #frame.data);
|
||||
|
||||
-- Error cases
|
||||
if frame.RSV1 or frame.RSV2 or frame.RSV3 then -- Reserved bits non zero
|
||||
- websocket_close(1002, "Reserved bits not zero");
|
||||
+ websocket_close(conn, 1002, "Reserved bits not zero");
|
||||
return false;
|
||||
end
|
||||
|
||||
if opcode == 0x8 then -- close frame
|
||||
if length == 1 then
|
||||
- websocket_close(1002, "Close frame with payload, but too short for status code");
|
||||
+ websocket_close(conn, 1002, "Close frame with payload, but too short for status code");
|
||||
return false;
|
||||
elseif length >= 2 then
|
||||
local status_code = parse_close(frame.data)
|
||||
if status_code < 1000 then
|
||||
- websocket_close(1002, "Closed with invalid status code");
|
||||
+ websocket_close(conn, 1002, "Closed with invalid status code");
|
||||
return false;
|
||||
elseif ((status_code > 1003 and status_code < 1007) or status_code > 1011) and status_code < 3000 then
|
||||
- websocket_close(1002, "Closed with reserved status code");
|
||||
+ websocket_close(conn, 1002, "Closed with reserved status code");
|
||||
return false;
|
||||
end
|
||||
end
|
||||
@@ -198,28 +198,28 @@ function handle_request(event)
|
||||
|
||||
if opcode >= 0x8 then
|
||||
if length > 125 then -- Control frame with too much payload
|
||||
- websocket_close(1002, "Payload too large");
|
||||
+ websocket_close(conn, 1002, "Payload too large");
|
||||
return false;
|
||||
end
|
||||
|
||||
if not frame.FIN then -- Fragmented control frame
|
||||
- websocket_close(1002, "Fragmented control frame");
|
||||
+ websocket_close(conn, 1002, "Fragmented control frame");
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
if (opcode > 0x2 and opcode < 0x8) or (opcode > 0xA) then
|
||||
- websocket_close(1002, "Reserved opcode");
|
||||
+ websocket_close(conn, 1002, "Reserved opcode");
|
||||
return false;
|
||||
end
|
||||
|
||||
if opcode == 0x0 and not dataBuffer then
|
||||
- websocket_close(1002, "Unexpected continuation frame");
|
||||
+ websocket_close(conn, 1002, "Unexpected continuation frame");
|
||||
return false;
|
||||
end
|
||||
|
||||
if (opcode == 0x1 or opcode == 0x2) and dataBuffer then
|
||||
- websocket_close(1002, "Continuation frame expected");
|
||||
+ websocket_close(conn, 1002, "Continuation frame expected");
|
||||
return false;
|
||||
end
|
||||
|
||||
@@ -229,11 +229,11 @@ function handle_request(event)
|
||||
elseif opcode == 0x1 then -- Text frame
|
||||
dataBuffer = {frame.data};
|
||||
elseif opcode == 0x2 then -- Binary frame
|
||||
- websocket_close(1003, "Only text frames are supported");
|
||||
+ websocket_close(conn, 1003, "Only text frames are supported");
|
||||
return;
|
||||
elseif opcode == 0x8 then -- Close request
|
||||
- websocket_close(1000, "Goodbye");
|
||||
- return;
|
||||
+ websocket_close(conn, 1000, "Goodbye");
|
||||
+ return "";
|
||||
elseif opcode == 0x9 then -- Ping frame
|
||||
frame.opcode = 0xA;
|
||||
conn:write(build_frame(frame));
|
||||
@@ -276,7 +276,7 @@ function handle_request(event)
|
||||
|
||||
while frame do
|
||||
frameBuffer = frameBuffer:sub(length + 1);
|
||||
- local result = handle_frame(frame);
|
||||
+ local result = handle_frame(session.conn, frame);
|
||||
if not result then return; end
|
||||
cache[#cache+1] = filter_open_close(result);
|
||||
frame, length = parse_frame(frameBuffer);
|
|
@ -22,11 +22,15 @@ local muc_domain = module:get_option_string(
|
|||
local escaped_muc_domain_base = muc_domain_base:gsub("%p", "%%%1");
|
||||
local escaped_muc_domain_prefix = muc_domain_prefix:gsub("%p", "%%%1");
|
||||
-- The pattern used to extract the target subdomain
|
||||
-- (e.g. extract 'foo' from 'foo.muc.example.com')
|
||||
-- (e.g. extract 'foo' from 'conference.foo.example.com')
|
||||
local target_subdomain_pattern
|
||||
= "^"..escaped_muc_domain_prefix..".([^%.]+)%."..escaped_muc_domain_base;
|
||||
|
||||
-- table to store all incoming iqs without roomname in it, like discoinfo to the muc compoent
|
||||
local roomless_iqs = {};
|
||||
|
||||
-- Utility function to split room JID to include room name and subdomain
|
||||
-- (e.g. from room1@conference.foo.example.com/res returns (room1, example.com, res, foo))
|
||||
local function room_jid_split_subdomain(room_jid)
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
local target_subdomain = host and host:match(target_subdomain_pattern);
|
||||
|
@ -34,39 +38,57 @@ local function room_jid_split_subdomain(room_jid)
|
|||
end
|
||||
|
||||
--- Utility function to check and convert a room JID from
|
||||
-- virtual room1@muc.foo.example.com to real [foo]room1@muc.example.com
|
||||
--- virtual room1@conference.foo.example.com to real [foo]room1@conference.example.com
|
||||
-- @param room_jid the room jid to match and rewrite if needed
|
||||
-- @return returns room jid [foo]room1@muc.example.com when it has subdomain
|
||||
-- otherwise room1@muc.example.com(the room_jid value untouched)
|
||||
local function room_jid_match_rewrite(room_jid)
|
||||
local node, host, resource, target_subdomain = room_jid_split_subdomain(room_jid);
|
||||
-- @param stanza the stanza
|
||||
-- @return returns room jid [foo]room1@conference.example.com when it has subdomain
|
||||
-- otherwise room1@conference.example.com(the room_jid value untouched)
|
||||
local function room_jid_match_rewrite(room_jid, stanza)
|
||||
local node, _, resource, target_subdomain = room_jid_split_subdomain(room_jid);
|
||||
if not target_subdomain then
|
||||
module:log("debug", "No need to rewrite out 'to' %s", room_jid);
|
||||
-- module:log("debug", "No need to rewrite out 'to' %s", room_jid);
|
||||
return room_jid;
|
||||
end
|
||||
-- Ok, rewrite room_jid address to new format
|
||||
local new_node, new_host, new_resource
|
||||
= "["..target_subdomain.."]"..node, muc_domain, resource;
|
||||
local new_node, new_host, new_resource;
|
||||
if node then
|
||||
new_node, new_host, new_resource = "["..target_subdomain.."]"..node, muc_domain, resource;
|
||||
else
|
||||
-- module:log("debug", "No room name provided so rewriting only host 'to' %s", room_jid);
|
||||
new_host, new_resource = muc_domain, resource;
|
||||
|
||||
if (stanza and stanza.attr and stanza.attr.id) then
|
||||
roomless_iqs[stanza.attr.id] = stanza.attr.to;
|
||||
end
|
||||
end
|
||||
room_jid = jid.join(new_node, new_host, new_resource);
|
||||
module:log("debug", "Rewrote to %s", room_jid);
|
||||
-- module:log("debug", "Rewrote to %s", room_jid);
|
||||
return room_jid
|
||||
end
|
||||
|
||||
local function internal_room_jid_match_rewrite(room_jid)
|
||||
-- Utility function to check and convert a room JID from real [foo]room1@muc.example.com to virtual room1@muc.foo.example.com
|
||||
local function internal_room_jid_match_rewrite(room_jid, stanza)
|
||||
local node, host, resource = jid.split(room_jid);
|
||||
if host ~= muc_domain or not node then
|
||||
module:log("debug", "No need to rewrite %s (not from the MUC host)", room_jid);
|
||||
-- module:log("debug", "No need to rewrite %s (not from the MUC host)", room_jid);
|
||||
|
||||
if (stanza and stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
|
||||
local result = roomless_iqs[stanza.attr.id];
|
||||
roomless_iqs[stanza.attr.id] = nil;
|
||||
return result;
|
||||
end
|
||||
|
||||
return room_jid;
|
||||
end
|
||||
local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$");
|
||||
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;
|
||||
end
|
||||
-- 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;
|
||||
room_jid = jid.join(new_node, new_host, new_resource);
|
||||
module:log("debug", "Rewrote to %s", room_jid);
|
||||
-- module:log("debug", "Rewrote to %s", room_jid);
|
||||
return room_jid
|
||||
end
|
||||
|
||||
|
@ -216,8 +238,8 @@ function is_healthcheck_room(room_jid)
|
|||
return false;
|
||||
end
|
||||
|
||||
-- Utility function to make an http get request and
|
||||
-- retry @param retry number of times
|
||||
--- Utility function to make an http get request and
|
||||
--- retry @param retry number of times
|
||||
-- @param url endpoint to be called
|
||||
-- @param retry nr of retries, if retry is
|
||||
-- nil there will be no retries
|
||||
|
|
Loading…
Reference in New Issue