mod_carbons/mod_carbons.lua
author Kim Alvefur <zash@zash.se>
Sat, 29 Oct 2011 19:59:48 +0200
changeset 462 f28a3f260fc2
child 463 7d6a05f94941
permissions -rw-r--r--
mod_carbons: Initial commit.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
462
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local st = require "util.stanza";
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local jid_bare = require "util.jid".bare;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
local jid_split = require "util.jid".split;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local xmlns_carbons = "urn:xmpp:carbons:1";
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local xmlns_forward = "urn:xmpp:forward:0";
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
local host_sessions = hosts[module.host].sessions;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
-- TODO merge message handlers into one somehow
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
module:hook("iq/self/"..xmlns_carbons..":enable", function(event)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	local origin, stanza = event.origin, event.stanza;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
	if stanza.attr.type == "set" then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
		module:log("debug", "%s enabled carbons", origin.full_jid);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
		origin.want_carbons = true;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
		origin.send(st.reply(stanza));
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
		return true
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
end);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
module:hook("iq/self/"..xmlns_carbons..":disable", function(event)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
	local origin, stanza = event.origin, event.stanza;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
	if stanza.attr.type == "set" then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
		module:log("debug", "%s disabled carbons", origin.full_jid);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
		origin.want_carbons = nil;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
		origin.send(st.reply(stanza));
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
		return true
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
end);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
function c2s_message_handler(event)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
	local origin, stanza = event.origin, event.stanza;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	local orig_type = stanza.attr.type;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	local orig_to = stanza.attr.to;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
	if not (orig_type == nil
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
			or orig_type == "normal"
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
			or orig_type == "chat") then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
		return
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	local bare_jid, user_sessions;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	if origin.type == "s2s" then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
		bare_jid = jid_bare(stanza.attr.from);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
		user_sessions = host_sessions[jid_split(orig_to)];
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	else
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
		bare_jid = (origin.username.."@"..origin.host)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
		user_sessions = host_sessions[origin.username];
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	if not stanza:get_child("private", xmlns_carbons)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
			and not stanza:get_child("forwarded", xmlns_forward) then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
		user_sessions = user_sessions and user_sessions.sessions;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
		for resource, session in pairs(user_sessions) do
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
			local full_jid = bare_jid .. "/" .. resource;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
			if session ~= origin and session.want_carbons then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
				local msg = st.clone(stanza);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
				msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
				local fwd = st.message{
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
							from = bare_jid,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
							to = full_jid,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
							type = orig_type,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
						}
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
					:tag("forwarded", { xmlns = xmlns_forward })
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
						:tag("received", { xmlns = xmlns_carbons }):up()
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
							:add_child(msg);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
				core_route_stanza(origin, fwd);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
			end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
		end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
function s2c_message_handler(event)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	local origin, stanza = event.origin, event.stanza;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
	local orig_type = stanza.attr.type;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
	local orig_to = stanza.attr.to;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
	if not (orig_type == nil
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
			or orig_type == "normal"
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
			or orig_type == "chat") then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
		return
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	local full_jid, bare_jid = orig_to, jid_bare(orig_to);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
	local username, hostname, resource = jid_split(full_jid);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
	local user_sessions = username and host_sessions[username];
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
	if not user_sessions or hostname ~= module.host then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
		return
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
	local no_carbon_to = {};
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
	if resource then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
		no_carbon_to[resource] = true;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	else
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
		local top_resources = user_sessions.top_resources;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
		for i=1,top_resources do
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
			no_carbon_to[top_resources[i]] = true;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
		end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
	if not stanza:get_child("private", xmlns_carbons)
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
			and not stanza:get_child("forwarded", xmlns_forward) then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
		user_sessions = user_sessions and user_sessions.sessions;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
		for resource, session in pairs(user_sessions) do
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
			local full_jid = bare_jid .. "/" .. resource;
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
			if not no_carbon_to[resource] and session.want_carbons then
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
				local msg = st.clone(stanza);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
				msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
				local fwd = st.message{
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
							from = bare_jid,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
							to = full_jid,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
							type = orig_type,
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
						}
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
					:tag("forwarded", { xmlns = xmlns_forward })
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
						:tag("received", { xmlns = xmlns_carbons }):up()
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
							:add_child(msg);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
				core_route_stanza(origin, fwd);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
			end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
		end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
	end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
end
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
-- Stanzas sent by local clients
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
module:hook("pre-message/bare", c2s_message_handler, 1);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
module:hook("pre-message/full", c2s_message_handler, 1);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
-- Stanszas to local clients
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
module:hook("message/bare", s2c_message_handler, 1); -- this will suck
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
module:hook("message/full", s2c_message_handler, 1);
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
f28a3f260fc2 mod_carbons: Initial commit.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
module:add_feature(xmlns_carbons);