--- a/mod_carbons/mod_carbons.lua Fri Nov 25 11:03:04 2011 +0100
+++ b/mod_carbons/mod_carbons.lua Sat Nov 26 09:06:04 2011 +0100
@@ -27,104 +27,78 @@
end
end);
-function c2s_message_handler(event)
+local function message_handler(event, c2s)
local origin, stanza = event.origin, event.stanza;
local orig_type = stanza.attr.type;
local orig_to = stanza.attr.to;
+ local orig_from = stanza.attr.from;
if not (orig_type == nil
or orig_type == "normal"
or orig_type == "chat") then
- return
+ return -- No carbons for messages of type error or headline
end
local bare_jid, user_sessions;
- if origin.type == "s2s" then
- bare_jid = jid_bare(stanza.attr.from);
- user_sessions = host_sessions[jid_split(orig_to)];
- else
+ local no_carbon_to = {};
+ module:log("debug", "origin (%s) type: %s", tostring(origin), origin.type)
+ if c2s then -- Stanza sent by a local client
bare_jid = (origin.username.."@"..origin.host)
user_sessions = host_sessions[origin.username];
+ else -- Stanza about to be delivered to a local client
+ local username, hostname, resource = jid_split(orig_to);
+ bare_jid = jid_bare(orig_to);
+ user_sessions = host_sessions[username];
+ if resource then
+ no_carbon_to[resource] = true;
+ else
+ local top_resources = user_sessions.top_resources;
+ for _, session in ipairs(top_resources) do
+ no_carbon_to[session.resource] = true;
+ end
+ end
end
- if not stanza:get_child("private", xmlns_carbons)
- and not stanza:get_child("forwarded", xmlns_forward) then
+ if not c2s and stanza:get_child("private", xmlns_carbons) then
+ stanza:maptags(function(tag)
+ return tag.attr.xmlns == xmlns_carbons
+ and tag.name == "private" and tag or nil;
+ end);
+ return
+ end
+
+ if not stanza:get_child("forwarded", xmlns_forward) then
user_sessions = user_sessions and user_sessions.sessions;
for resource, session in pairs(user_sessions) do
local full_jid = bare_jid .. "/" .. resource;
- if session ~= origin and session.want_carbons then
- local msg = st.clone(stanza);
- msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
- local fwd = st.message{
- from = bare_jid,
- to = full_jid,
- type = orig_type,
- }
- :tag("forwarded", { xmlns = xmlns_forward })
- :tag("sent", { xmlns = xmlns_carbons }):up()
- :add_child(msg);
- core_route_stanza(origin, fwd);
+ if session.want_carbons then
+ if (c2s and session ~= origin) or (not c2s and not no_carbon_to[resource]) then
+ local msg = st.clone(stanza);
+ msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
+ local fwd = st.message{
+ from = bare_jid,
+ to = full_jid,
+ type = orig_type,
+ }
+ :tag("forwarded", { xmlns = xmlns_forward })
+ :tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up()
+ :add_child(msg);
+ core_post_stanza(origin, fwd);
+ end
end
end
end
end
-function s2c_message_handler(event)
- local origin, stanza = event.origin, event.stanza;
- local orig_type = stanza.attr.type;
- local orig_to = stanza.attr.to;
-
- if not (orig_type == nil
- or orig_type == "normal"
- or orig_type == "chat") then
- return
- end
-
- local full_jid, bare_jid = orig_to, jid_bare(orig_to);
- local username, hostname, resource = jid_split(full_jid);
- local user_sessions = username and host_sessions[username];
- if not user_sessions or hostname ~= module.host then
- return
- end
-
- local no_carbon_to = {};
- if resource then
- no_carbon_to[resource] = true;
- else
- local top_resources = user_sessions.top_resources;
- for i, session in ipairs(top_resources) do
- no_carbon_to[session.resource] = true;
- module:log("debug", "not going to send to /%s", resource);
- end
- end
-
- if not stanza:get_child("private", xmlns_carbons)
- and not stanza:get_child("forwarded", xmlns_forward) then
- user_sessions = user_sessions and user_sessions.sessions;
- for resource, session in pairs(user_sessions) do
- local full_jid = bare_jid .. "/" .. resource;
- if not no_carbon_to[resource] and session.want_carbons then
- local msg = st.clone(stanza);
- msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
- local fwd = st.message{
- from = bare_jid,
- to = full_jid,
- type = orig_type,
- }
- :tag("forwarded", { xmlns = xmlns_forward })
- :tag("received", { xmlns = xmlns_carbons }):up()
- :add_child(msg);
- core_route_stanza(origin, fwd);
- end
- end
- end
+local function c2s_message_handler(event)
+ return message_handler(event, true)
end
-- Stanzas sent by local clients
module:hook("pre-message/bare", c2s_message_handler, 1);
module:hook("pre-message/full", c2s_message_handler, 1);
-- Stanszas to local clients
-module:hook("message/bare", s2c_message_handler, 1);
-module:hook("message/full", s2c_message_handler, 1);
+module:hook("message/bare", message_handler, 1);
+module:hook("message/full", message_handler, 1);
module:add_feature(xmlns_carbons);