diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 0915d21d3..db7fb9bdf 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -633,7 +633,7 @@ route_probe_reply(From, #{jid := To, Subscription = get_subscription(To, From), if IsAnotherResource orelse Subscription == both orelse Subscription == from -> - Packet = xmpp_util:add_delay_info(LastPres, To, TS), + Packet = misc:add_delay_info(LastPres, To, TS), case privacy_check_packet(State, Packet, out) of deny -> ok; diff --git a/src/misc.erl b/src/misc.erl index 8bf7d43a6..8a44f2b6b 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -28,7 +28,9 @@ -module(misc). %% API --export([tolower/1, term_to_base64/1, base64_to_term/1, ip_to_list/1, +-export([add_delay_info/3, add_delay_info/4, + unwrap_carbon/1, is_standalone_chat_state/1, + tolower/1, term_to_base64/1, base64_to_term/1, ip_to_list/1, hex_to_bin/1, hex_to_base64/1, url_encode/1, expand_keyword/3, atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1, @@ -44,11 +46,63 @@ {encode_base64, 1}]). -include("logger.hrl"). +-include("xmpp.hrl"). -include_lib("kernel/include/file.hrl"). %%%=================================================================== %%% API %%%=================================================================== +-spec add_delay_info(stanza(), jid(), erlang:timestamp()) -> stanza(). +add_delay_info(Stz, From, Time) -> + add_delay_info(Stz, From, Time, <<"">>). + +-spec add_delay_info(stanza(), jid(), erlang:timestamp(), binary()) -> stanza(). +add_delay_info(Stz, From, Time, Desc) -> + NewDelay = #delay{stamp = Time, from = From, desc = Desc}, + case xmpp:get_subtag(Stz, #delay{stamp = {0,0,0}}) of + #delay{from = OldFrom} when is_record(OldFrom, jid) -> + case jid:tolower(From) == jid:tolower(OldFrom) of + true -> + Stz; + false -> + xmpp:append_subtags(Stz, [NewDelay]) + end; + _ -> + xmpp:append_subtags(Stz, [NewDelay]) + end. + +-spec unwrap_carbon(stanza()) -> xmpp_element(). +unwrap_carbon(#message{} = Msg) -> + try + case xmpp:get_subtag(Msg, #carbons_sent{forwarded = #forwarded{}}) of + #carbons_sent{forwarded = #forwarded{sub_els = [El]}} -> + xmpp:decode(El, ?NS_CLIENT, [ignore_els]); + _ -> + case xmpp:get_subtag(Msg, #carbons_received{ + forwarded = #forwarded{}}) of + #carbons_received{forwarded = #forwarded{sub_els = [El]}} -> + xmpp:decode(El, ?NS_CLIENT, [ignore_els]); + _ -> + Msg + end + end + catch _:{xmpp_codec, _} -> + Msg + end; +unwrap_carbon(Stanza) -> Stanza. + +-spec is_standalone_chat_state(stanza()) -> boolean(). +is_standalone_chat_state(Stanza) -> + case unwrap_carbon(Stanza) of + #message{body = [], subject = [], sub_els = Els} -> + IgnoreNS = [?NS_CHATSTATES, ?NS_DELAY, ?NS_EVENT], + Stripped = [El || El <- Els, + not lists:member(xmpp:get_ns(El), IgnoreNS)], + Stripped == []; + _ -> + false + end. + -spec tolower(binary()) -> binary(). tolower(B) -> iolist_to_binary(tolower_s(binary_to_list(B))). diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index 99a810fdb..156fde726 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -237,7 +237,7 @@ filter_chat_states({#message{meta = #{csi_resend := true}}, _} = Acc) -> Acc; filter_chat_states({#message{from = From, to = To} = Msg, #{csi_state := inactive} = C2SState} = Acc) -> - case xmpp_util:is_standalone_chat_state(Msg) of + case misc:is_standalone_chat_state(Msg) of true -> case {From, To} of {#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}} -> @@ -352,7 +352,7 @@ flush_stanzas(#{lserver := LServer} = C2SState, Elems) -> -spec add_delay_info(stanza(), binary(), csi_timestamp()) -> stanza(). add_delay_info(Stanza, LServer, {_Seq, TimeStamp}) -> - Stanza1 = xmpp_util:add_delay_info( + Stanza1 = misc:add_delay_info( Stanza, jid:make(LServer), TimeStamp, <<"Client Inactive">>), xmpp:put_meta(Stanza1, csi_resend, true). diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 267514b20..aeb031763 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -2562,7 +2562,7 @@ add_message_to_history(FromNick, FromJID, Packet, StateData) -> jid = FromJID}]}, xmpp:set_subtag(Packet, Addresses) end, - TSPacket = xmpp_util:add_delay_info( + TSPacket = misc:add_delay_info( AddrPacket, StateData#state.jid, TimeStamp), SPacket = xmpp:set_from_to( TSPacket, diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 9e8af2c16..53e437020 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -384,7 +384,7 @@ need_to_store(LServer, #message{type = Type} = Packet) -> false -> Packet#message.body /= []; unless_chat_state -> - not xmpp_util:is_standalone_chat_state(Packet) + not misc:is_standalone_chat_state(Packet) end end; true -> @@ -795,8 +795,8 @@ add_delay_info(Packet, LServer, TS) -> _ -> TS end, Packet1 = xmpp:put_meta(Packet, from_offline, true), - xmpp_util:add_delay_info(Packet1, jid:make(LServer), NewTS, - <<"Offline storage">>). + misc:add_delay_info(Packet1, jid:make(LServer), NewTS, + <<"Offline storage">>). -spec get_priority_from_presence(presence()) -> integer(). get_priority_from_presence(#presence{priority = Prio}) -> diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 0e764c269..c114b1dce 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -48,7 +48,7 @@ store_message(#offline_msg{us = {LUser, LServer}} = M) -> From = M#offline_msg.from, To = M#offline_msg.to, Packet = xmpp:set_from_to(M#offline_msg.packet, From, To), - NewPacket = xmpp_util:add_delay_info( + NewPacket = misc:add_delay_info( Packet, jid:make(LServer), M#offline_msg.timestamp, <<"Offline Storage">>), @@ -198,7 +198,7 @@ export(_Server) -> try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of Packet -> Packet1 = xmpp:set_from_to(Packet, From, To), - Packet2 = xmpp_util:add_delay_info( + Packet2 = misc:add_delay_info( Packet1, jid:make(LServer), TimeStamp, <<"Offline Storage">>), XML = fxml:element_to_binary(xmpp:encode(Packet2)), diff --git a/src/mod_push.erl b/src/mod_push.erl index 760f6e540..cadce92b0 100644 --- a/src/mod_push.erl +++ b/src/mod_push.erl @@ -635,7 +635,7 @@ make_summary(_Host, _Pkt, _Dir) -> -spec unwrap_carbon(stanza()) -> stanza(). unwrap_carbon(#message{meta = #{carbon_copy := true}} = Msg) -> - xmpp_util:unwrap_carbon(Msg); + misc:unwrap_carbon(Msg); unwrap_carbon(Stanza) -> Stanza. diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index de10654e7..1927afa95 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -706,7 +706,7 @@ make_resume_id(#{sid := {Time, _}, resource := Resource}) -> (state(), xmlel(), erlang:timestamp()) -> xmlel(). add_resent_delay_info(#{lserver := LServer}, El, Time) when is_record(El, message); is_record(El, presence) -> - xmpp_util:add_delay_info(El, jid:make(LServer), Time, <<"Resent">>); + misc:add_delay_info(El, jid:make(LServer), Time, <<"Resent">>); add_resent_delay_info(_State, El, _Time) -> %% TODO El.