From 8e27decdfd9f91bc9ae2c01bc4df2ca7254d8242 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 9 Jul 2015 13:01:37 +0300 Subject: [PATCH] Fix mod_mam compatibility with RSM for other backends --- src/mod_mam.erl | 32 +++++++++++++++++--------------- test/ejabberd_SUITE.erl | 29 +++++++++++++++++++++++++++++ tools/xmpp_codec.erl | 4 ++-- tools/xmpp_codec.hrl | 2 +- tools/xmpp_codec.spec | 1 + 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/mod_mam.erl b/src/mod_mam.erl index cd869c9d8..4e58f9ffb 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -663,21 +663,23 @@ filter_by_rsm(_Msgs, #rsm_in{max = Max}) when Max =< 0 -> []; filter_by_rsm(Msgs, #rsm_in{max = Max, direction = Direction, id = ID}) -> NewMsgs = case Direction of - aft -> - lists:filter( - fun(#archive_msg{id = I}) -> - I > ID - end, Msgs); - before -> - lists:foldl( - fun(#archive_msg{id = I} = Msg, Acc) when I < ID -> - [Msg|Acc]; - (_, Acc) -> - Acc - end, [], Msgs); - _ -> - Msgs - end, + aft when ID /= <<"">> -> + lists:filter( + fun(#archive_msg{id = I}) -> + I > ID + end, Msgs); + before when ID /= <<"">> -> + lists:foldl( + fun(#archive_msg{id = I} = Msg, Acc) when I < ID -> + [Msg|Acc]; + (_, Acc) -> + Acc + end, [], Msgs); + before when ID == <<"">> -> + lists:reverse(Msgs); + _ -> + Msgs + end, filter_by_max(NewMsgs, Max). filter_by_max(Msgs, undefined) -> diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl index 470055654..8cd21d5e9 100644 --- a/test/ejabberd_SUITE.erl +++ b/test/ejabberd_SUITE.erl @@ -1854,6 +1854,35 @@ mam_query_rsm(Config, NS) -> rsm = #rsm_set{count = 10, first = undefined, last = undefined}}]}) + end, + %% Should receive 2 last messages + I5 = send(Config, + #iq{type = Type, + sub_els = [#mam_query{xmlns = NS, + rsm = #rsm_set{max = 2, + before = none}}]}), + maybe_recv_iq_result(NS, I5), + lists:foreach( + fun(N) -> + Text = #text{data = jlib:integer_to_binary(N)}, + ?recv1(#message{to = MyJID, + sub_els = + [#mam_result{ + xmlns = NS, + sub_els = + [#forwarded{ + delay = #delay{}, + sub_els = + [#message{ + from = MyJID, to = Peer, + body = [Text]}]}]}]}) + end, lists:seq(4, 5)), + if NS == ?NS_MAM_TMP -> + ?recv1(#iq{type = result, id = I5, + sub_els = [#mam_query{xmlns = NS, rsm = #rsm_set{count = 5}}]}); + true -> + ?recv1(#message{ + sub_els = [#mam_fin{rsm = #rsm_set{count = 10}}]}) end. client_state_master(Config) -> diff --git a/tools/xmpp_codec.erl b/tools/xmpp_codec.erl index 0dbc62808..08a2e84ca 100644 --- a/tools/xmpp_codec.erl +++ b/tools/xmpp_codec.erl @@ -4746,10 +4746,10 @@ encode_rsm_before(Cdata, _xmlns_attrs) -> _attrs = _xmlns_attrs, {xmlel, <<"before">>, _attrs, _els}. -decode_rsm_before_cdata(__TopXMLNS, <<>>) -> undefined; +decode_rsm_before_cdata(__TopXMLNS, <<>>) -> none; decode_rsm_before_cdata(__TopXMLNS, _val) -> _val. -encode_rsm_before_cdata(undefined, _acc) -> _acc; +encode_rsm_before_cdata(none, _acc) -> _acc; encode_rsm_before_cdata(_val, _acc) -> [{xmlcdata, _val} | _acc]. diff --git a/tools/xmpp_codec.hrl b/tools/xmpp_codec.hrl index 567946fe2..fa8e5e74d 100644 --- a/tools/xmpp_codec.hrl +++ b/tools/xmpp_codec.hrl @@ -280,7 +280,7 @@ units = [] :: [binary()]}). -record(rsm_set, {'after' :: binary(), - before :: binary(), + before :: 'none' | binary(), count :: non_neg_integer(), first :: #rsm_first{}, index :: non_neg_integer(), diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec index dfa516ef5..326d1de36 100644 --- a/tools/xmpp_codec.spec +++ b/tools/xmpp_codec.spec @@ -2071,6 +2071,7 @@ -xml(rsm_before, #elem{name = <<"before">>, xmlns = <<"http://jabber.org/protocol/rsm">>, + cdata = #cdata{default = none}, result = '$cdata'}). -xml(rsm_last,