diff options
author | badlop <badlop@ono.com> | 2014-04-22 15:52:11 +0400 |
---|---|---|
committer | badlop <badlop@ono.com> | 2014-04-22 15:52:11 +0400 |
commit | 37d4109e8a90e55f1358751c79992470c3f40c5e (patch) | |
tree | 16e747c7863b4dfc03e3b14d55c22d49f8f42056 /src/mod_carboncopy.erl | |
parent | b73f28c93ebf7d91af43f10ae66b2c8bc6e15012 (diff) | |
parent | b3b12effbca94f9b16c3317fa8fdd9b2f4c5554b (diff) |
Merge pull request #161 from weiss/fix-carbons
Let mod_carboncopy take care of messages sent to bare/unavailable JIDs
Diffstat (limited to 'src/mod_carboncopy.erl')
-rw-r--r-- | src/mod_carboncopy.erl | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 69362bd77..16f0c06fc 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -127,23 +127,18 @@ iq_handler(From, _To, #iq{type=set, sub_el = #xmlel{name = Operation, children iq_handler(_From, _To, IQ, _CC)-> IQ#iq{type=error, sub_el = [?ERR_NOT_ALLOWED]}. -user_send_packet(From, _To, Packet) -> - check_and_forward(From, Packet, sent). +user_send_packet(From, To, Packet) -> + check_and_forward(From, To, Packet, sent). -%% Only make carbon copies if the original destination was not a bare jid. -%% If the original destination was a bare jid, the message is going to be delivered to all -%% connected resources anyway. Avoid duplicate delivery. "XEP-0280 : 3.5 Receiving Messages" -user_receive_packet(JID, _From, #jid{resource=Resource} = _To, Packet) when Resource /= <<>> -> - check_and_forward(JID, Packet, received); -user_receive_packet(_JID, _From, _To, _Packet) -> - ok. +user_receive_packet(JID, _From, To, Packet) -> + check_and_forward(JID, To, Packet, received). % verifier si le trafic est local % Modified from original version: % - registered to the user_send_packet hook, to be called only once even for multicast % - do not support "private" message mode, and do not modify the original packet in any way % - we also replicate "read" notifications -check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Direction)-> +check_and_forward(JID, To, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Direction)-> case xml:get_attr_s(<<"type">>, Attrs) of <<"chat">> -> case xml:get_subtag(Packet, <<"private">>) of @@ -154,11 +149,11 @@ check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Dir %% receiving message back to original sender. SubTag = xml:get_subtag(Packet,<<"sent">>), if SubTag == false -> - send_copies(JID, Packet, Direction); + send_copies(JID, To, Packet, Direction); true -> case xml:get_subtag(SubTag,<<"forwarded">>) of false-> - send_copies(JID, Packet, Direction); + send_copies(JID, To, Packet, Direction); _ -> stop end @@ -174,7 +169,7 @@ check_and_forward(JID, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, Dir ok end; -check_and_forward(_JID, _Packet, _)-> ok. +check_and_forward(_JID, _To, _Packet, _)-> ok. remove_connection(User, Server, Resource, _Status)-> disable(Server, User, Resource), @@ -183,14 +178,35 @@ remove_connection(User, Server, Resource, _Status)-> %%% Internal %% Direction = received | sent <received xmlns='urn:xmpp:carbons:1'/> -send_copies(JID, Packet, Direction)-> +send_copies(JID, To, Packet, Direction)-> {U, S, R} = jlib:jid_tolower(JID), + PrioRes = ejabberd_sm:get_user_present_resources(U, S), + IsBareTo = case {Direction, To} of + {received, #jid{lresource = <<>>}} -> true; + {received, #jid{lresource = LRes}} -> + %% unavailable resources are handled like bare JIDs + case lists:keyfind(LRes, 2, PrioRes) of + false -> true; + _ -> false + end; + _ -> false + end, %% list of JIDs that should receive a carbon copy of this message (excluding the - %% receiver of the original message - TargetJIDs = [ {jlib:make_jid({U, S, CCRes}), CC_Version} || {CCRes, CC_Version} <- list(U, S), CCRes /= R ], - %TargetJIDs = lists:delete(JID, [ jlib:make_jid({U, S, CCRes}) || CCRes <- list(U, S) ]), - + %% receiver(s) of the original message + TargetJIDs = if IsBareTo -> + MaxPrio = case catch lists:max(PrioRes) of + {Prio, _Res} -> Prio; + _ -> 0 + end, + OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end, + [ {jlib:make_jid({U, S, CCRes}), CC_Version} + || {CCRes, CC_Version} <- list(U, S), not OrigTo(CCRes) ]; + true -> + [ {jlib:make_jid({U, S, CCRes}), CC_Version} + || {CCRes, CC_Version} <- list(U, S), CCRes /= R ] + %TargetJIDs = lists:delete(JID, [ jlib:make_jid({U, S, CCRes}) || CCRes <- list(U, S) ]), + end, lists:map(fun({Dest,Version}) -> {_, _, Resource} = jlib:jid_tolower(Dest), |