aboutsummaryrefslogtreecommitdiff
path: root/src/mod_client_state.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_client_state.erl')
-rw-r--r--src/mod_client_state.erl139
1 files changed, 64 insertions, 75 deletions
diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl
index 9d37d4f5b..2bae7a4f8 100644
--- a/src/mod_client_state.erl
+++ b/src/mod_client_state.erl
@@ -39,7 +39,7 @@
-include("ejabberd.hrl").
-include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
-define(CSI_QUEUE_MAX, 100).
@@ -151,67 +151,68 @@ depends(_Host, _Opts) ->
%% ejabberd_hooks callbacks.
%%--------------------------------------------------------------------
--spec filter_presence({term(), [xmlel()]}, binary(), jid(), xmlel())
- -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}.
+-spec filter_presence({ejabberd_c2s:state(), [stanza()]}, binary(), jid(), stanza())
+ -> {ejabberd_c2s:state(), [stanza()]} |
+ {stop, {ejabberd_c2s:state(), [stanza()]}}.
filter_presence({C2SState, _OutStanzas} = Acc, Host, To,
- #xmlel{name = <<"presence">>, attrs = Attrs} = Stanza) ->
- case fxml:get_attr(<<"type">>, Attrs) of
- {value, Type} when Type /= <<"unavailable">> ->
- Acc;
- _ ->
- ?DEBUG("Got availability presence stanza for ~s",
- [jid:to_string(To)]),
- queue_add(presence, Stanza, Host, C2SState)
+ #presence{type = Type} = Stanza) ->
+ if Type == available; Type == unavailable ->
+ ?DEBUG("Got availability presence stanza for ~s",
+ [jid:to_string(To)]),
+ queue_add(presence, Stanza, Host, C2SState);
+ true ->
+ Acc
end;
filter_presence(Acc, _Host, _To, _Stanza) -> Acc.
--spec filter_chat_states({term(), [xmlel()]}, binary(), jid(), xmlel())
- -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}.
+-spec filter_chat_states({ejabberd_c2s:state(), [stanza()]}, binary(), jid(), stanza())
+ -> {ejabberd_c2s:state(), [stanza()]} |
+ {stop, {ejabberd_c2s:state(), [stanza()]}}.
filter_chat_states({C2SState, _OutStanzas} = Acc, Host, To,
- #xmlel{name = <<"message">>} = Stanza) ->
- case jlib:is_standalone_chat_state(Stanza) of
- true ->
- From = fxml:get_tag_attr_s(<<"from">>, Stanza),
- case {jid:from_string(From), To} of
- {#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}} ->
- %% Don't queue (carbon copies of) chat states from other
- %% resources, as they might be used to sync the state of
- %% conversations across clients.
- Acc;
- _ ->
+ #message{from = From} = Stanza) ->
+ case xmpp_util:is_standalone_chat_state(Stanza) of
+ true ->
+ case {From, To} of
+ {#jid{luser = U, lserver = S}, #jid{luser = U, lserver = S}} ->
+ %% Don't queue (carbon copies of) chat states from other
+ %% resources, as they might be used to sync the state of
+ %% conversations across clients.
+ Acc;
+ _ ->
?DEBUG("Got standalone chat state notification for ~s",
[jid:to_string(To)]),
- queue_add(chatstate, Stanza, Host, C2SState)
- end;
- false ->
- Acc
+ queue_add(chatstate, Stanza, Host, C2SState)
+ end;
+ false ->
+ Acc
end;
filter_chat_states(Acc, _Host, _To, _Stanza) -> Acc.
--spec filter_pep({term(), [xmlel()]}, binary(), jid(), xmlel())
- -> {term(), [xmlel()]} | {stop, {term(), [xmlel()]}}.
+-spec filter_pep({ejabberd_c2s:state(), [stanza()]}, binary(), jid(), stanza())
+ -> {ejabberd_c2s:state(), [stanza()]} |
+ {stop, {ejabberd_c2s:state(), [stanza()]}}.
-filter_pep({C2SState, _OutStanzas} = Acc, Host, To,
- #xmlel{name = <<"message">>} = Stanza) ->
+filter_pep({C2SState, _OutStanzas} = Acc, Host, To, #message{} = Stanza) ->
case get_pep_node(Stanza) of
- {value, Node} ->
- ?DEBUG("Got PEP notification for ~s", [jid:to_string(To)]),
- queue_add({pep, Node}, Stanza, Host, C2SState);
- false ->
- Acc
+ undefined ->
+ Acc;
+ Node ->
+ ?DEBUG("Got PEP notification for ~s", [jid:to_string(To)]),
+ queue_add({pep, Node}, Stanza, Host, C2SState)
end;
filter_pep(Acc, _Host, _To, _Stanza) -> Acc.
--spec filter_other({term(), [xmlel()]}, binary(), jid(), xmlel())
- -> {term(), [xmlel()]}.
+-spec filter_other({ejabberd_c2s:state(), [stanza()]}, binary(), jid(), stanza())
+ -> {ejabberd_c2s:state(), [stanza()]}.
filter_other({C2SState, _OutStanzas}, Host, To, Stanza) ->
?DEBUG("Won't add stanza for ~s to CSI queue", [jid:to_string(To)]),
queue_take(Stanza, Host, C2SState).
--spec flush_queue({term(), [xmlel()]}, binary(), jid()) -> {term(), [xmlel()]}.
+-spec flush_queue({ejabberd_c2s:state(), [stanza()]}, binary(), jid())
+ -> {ejabberd_c2s:state(), [stanza()]}.
flush_queue({C2SState, _OutStanzas}, Host, JID) ->
?DEBUG("Going to flush CSI queue of ~s", [jid:to_string(JID)]),
@@ -219,20 +220,17 @@ flush_queue({C2SState, _OutStanzas}, Host, JID) ->
NewState = set_queue([], C2SState),
{NewState, get_stanzas(Queue, Host)}.
--spec add_stream_feature([xmlel()], binary) -> [xmlel()].
+-spec add_stream_feature([stanza()], binary) -> [stanza()].
add_stream_feature(Features, _Host) ->
- Feature = #xmlel{name = <<"csi">>,
- attrs = [{<<"xmlns">>, ?NS_CLIENT_STATE}],
- children = []},
- [Feature | Features].
+ [#feature_csi{xmlns = <<"urn:xmpp:csi:0">>} | Features].
%%--------------------------------------------------------------------
%% Internal functions.
%%--------------------------------------------------------------------
--spec queue_add(csi_type(), xmlel(), binary(), term())
- -> {stop, {term(), [xmlel()]}}.
+-spec queue_add(csi_type(), stanza(), binary(), term())
+ -> {stop, {term(), [stanza()]}}.
queue_add(Type, Stanza, Host, C2SState) ->
case get_queue(C2SState) of
@@ -242,19 +240,19 @@ queue_add(Type, Stanza, Host, C2SState) ->
{stop, {NewState, get_stanzas(Queue, Host) ++ [Stanza]}};
Queue ->
?DEBUG("Adding stanza to CSI queue", []),
- From = fxml:get_tag_attr_s(<<"from">>, Stanza),
- Key = {jid:tolower(jid:from_string(From)), Type},
+ From = xmpp:get_from(Stanza),
+ Key = {jid:tolower(From), Type},
Entry = {Key, p1_time_compat:timestamp(), Stanza},
NewQueue = lists:keystore(Key, 1, Queue, Entry),
NewState = set_queue(NewQueue, C2SState),
{stop, {NewState, []}}
end.
--spec queue_take(xmlel(), binary(), term()) -> {term(), [xmlel()]}.
+-spec queue_take(stanza(), binary(), term()) -> {term(), [stanza()]}.
queue_take(Stanza, Host, C2SState) ->
- From = fxml:get_tag_attr_s(<<"from">>, Stanza),
- {LUser, LServer, _LResource} = jid:tolower(jid:from_string(From)),
+ From = xmpp:get_from(Stanza),
+ {LUser, LServer, _LResource} = jid:tolower(From),
{Selected, Rest} = lists:partition(
fun({{{U, S, _R}, _Type}, _Time, _Stanza}) ->
U == LUser andalso S == LServer
@@ -277,32 +275,23 @@ get_queue(C2SState) ->
[]
end.
--spec get_stanzas(csi_queue(), binary()) -> [xmlel()].
+-spec get_stanzas(csi_queue(), binary()) -> [stanza()].
get_stanzas(Queue, Host) ->
lists:map(fun({_Key, Time, Stanza}) ->
- jlib:add_delay_info(Stanza, Host, Time,
- <<"Client Inactive">>)
+ xmpp_util:add_delay_info(Stanza, jid:make(Host), Time,
+ <<"Client Inactive">>)
end, Queue).
--spec get_pep_node(xmlel()) -> {value, binary()} | false.
-
-get_pep_node(#xmlel{name = <<"message">>} = Stanza) ->
- From = fxml:get_tag_attr_s(<<"from">>, Stanza),
- case jid:from_string(From) of
- #jid{luser = <<>>} -> % It's not PEP.
- false;
- _ ->
- case fxml:get_subtag_with_xmlns(Stanza, <<"event">>,
- ?NS_PUBSUB_EVENT) of
- #xmlel{children = Els} ->
- case fxml:remove_cdata(Els) of
- [#xmlel{name = <<"items">>, attrs = ItemsAttrs}] ->
- fxml:get_attr(<<"node">>, ItemsAttrs);
- _ ->
- false
- end;
- false ->
- false
- end
+-spec get_pep_node(message()) -> binary() | undefined.
+
+get_pep_node(#message{from = #jid{luser = <<>>}}) ->
+ %% It's not PEP.
+ undefined;
+get_pep_node(#message{} = Msg) ->
+ case xmpp:get_subtag(Msg, #ps_event{}) of
+ #ps_event{items = #ps_items{node = Node}} ->
+ Node;
+ _ ->
+ undefined
end.