Software /
code /
prosody-modules
File
mod_carbons/mod_carbons.lua @ 638:60cee6923ee7
Tagging last 0.8.x compatible revision of this repo, for 0.8.x support move to http://code.google.com/p/prosody-modules.0-8/
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 28 Apr 2012 17:44:28 +0100 |
parent | 618:267548522810 |
child | 664:2f11d2473afd |
line wrap: on
line source
-- XEP-0280: Message Carbons implementation for Prosody -- Copyright (C) 2011 Kim Alvefur -- -- This file is MIT/X11 licensed. local st = require "util.stanza"; local jid_bare = require "util.jid".bare; local jid_split = require "util.jid".split; local xmlns_carbons = "urn:xmpp:carbons:1"; local xmlns_forward = "urn:xmpp:forward:0"; local host_sessions = hosts[module.host].sessions; module:hook("iq/self/"..xmlns_carbons..":enable", function(event) local origin, stanza = event.origin, event.stanza; if stanza.attr.type == "set" then module:log("debug", "%s enabled carbons", origin.full_jid); origin.want_carbons = true; origin.send(st.reply(stanza)); return true end end); module:hook("iq/self/"..xmlns_carbons..":disable", function(event) local origin, stanza = event.origin, event.stanza; if stanza.attr.type == "set" then module:log("debug", "%s disabled carbons", origin.full_jid); origin.want_carbons = nil; origin.send(st.reply(stanza)); return true end end); 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 -- No carbons for messages of type error or headline end local bare_jid, user_sessions; local no_carbon_to = {}; module:log("debug", "Message from %s to %s", tostring(orig_from), tostring(orig_to)); 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 module:log("debug", "Message was to resource %s, it will not get carbon", resource); no_carbon_to[resource] = true; elseif user_sessions then local top_resources = user_sessions.top_resources; if top_resources then for _, session in ipairs(top_resources) do module:log("debug", "Not sending carbons to top resource %s", session.resource); no_carbon_to[session.resource] = true; end end end end if not user_sessions then module:log("debug", "Skip carbons for offline user"); return -- No use in sending carbons to an offline user end 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); module:log("debug", "Message tagged private, ignoring"); return end user_sessions = user_sessions and user_sessions.sessions; for resource, session in pairs(user_sessions) do local full_jid = bare_jid .. "/" .. resource; module:log("debug", "%s wants carbons: %s", session.full_jid, tostring(session.want_carbons)); if session.want_carbons then if c2s then module:log("debug", "Session is origin: %s", tostring(session == origin)); else module:log("debug", "Session is in ignore list: %s", tostring(no_carbon_to[resource])); end 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(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up() :tag("forwarded", { xmlns = xmlns_forward }) :add_child(msg); module:log("debug", "Sending carbon"); session.send(fwd); end 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); -- Stanzas to local clients module:hook("message/bare", message_handler, 1); module:hook("message/full", message_handler, 1); module:add_feature(xmlns_carbons);