25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-22 17:28:25 +01:00

Add more control for decoding IQ payloads

This commit is contained in:
Evgeniy Khramtsov 2016-11-13 14:17:21 +03:00
parent 7e9f1a6dc1
commit ebefd0d8d6
4 changed files with 20 additions and 14 deletions

View File

@ -96,13 +96,7 @@ process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set ->
Err = xmpp:make_error(Packet, xmpp:err_bad_request()),
ejabberd_router:route(To, From, Err);
process_iq(From, To, #iq{type = T} = Packet) when T == result; T == error ->
try
NewPacket = xmpp:decode_els(Packet),
process_iq_reply(From, To, NewPacket)
catch _:{xmpp_codec, Why} ->
?DEBUG("failed to decode iq-result ~p: ~s",
[Packet, xmpp:format_error(Why)])
end.
process_iq_reply(From, To, Packet).
-spec process_iq_reply(jid(), jid(), iq()) -> any().
process_iq_reply(From, To, #iq{id = ID} = IQ) ->

View File

@ -153,11 +153,9 @@ process_iq(_Host, Module, Function, From, To, IQ0) ->
-spec process_iq(module(), atom(), iq()) -> ignore | iq().
process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) ->
try
%% TODO: move this 'conditional' decoding somewhere
%% IQ handler should know *nothing* about vCards.
Pkt = case xmpp:get_ns(El) of
?NS_VCARD when Module == mod_vcard -> El;
_ -> xmpp:decode(El)
Pkt = case erlang:function_exported(Module, decode_iq_subel, 1) of
true -> Module:decode_iq_subel(El);
false -> xmpp:decode(El)
end,
Module:Function(IQ#iq{sub_els = [Pkt]})
catch error:{xmpp_codec, Why} ->

View File

@ -18,7 +18,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([component_connected/1, component_disconnected/2,
ejabberd_local/1, ejabberd_sm/1,
ejabberd_local/1, ejabberd_sm/1, decode_iq_subel/1,
disco_local_features/5, disco_sm_features/5,
disco_local_identity/5, disco_sm_identity/5]).
@ -56,6 +56,12 @@ mod_opt_type(_) ->
depends(_, _) ->
[].
-spec decode_iq_subel(xmpp_element()) -> xmpp_element();
(xmlel()) -> xmlel().
%% Tell gen_iq_handler not to auto-decode IQ payload
decode_iq_subel(El) ->
El.
-spec component_connected(binary()) -> ok.
component_connected(Host) ->
lists:foreach(

View File

@ -37,7 +37,7 @@
remove_user/2, export/1, import/1, import/3, depends/2,
process_search/1, process_vcard/1, get_vcard/2,
disco_items/5, disco_features/5, disco_identity/5,
mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
-include("ejabberd.hrl").
-include("logger.hrl").
@ -167,6 +167,14 @@ get_sm_features(Acc, _From, _To, Node, _Lang) ->
_ -> Acc
end.
-spec decode_iq_subel(xmpp_element() | xmlel()) -> xmpp_element() | xmlel().
%% Tell gen_iq_handler not to decode vcard elements
decode_iq_subel(El) ->
case xmpp:get_ns(El) of
?NS_VCARD -> xmpp:encode(El);
_ -> xmpp:decode(El)
end.
-spec process_local_iq(iq()) -> iq().
process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,