Navigation Menu

Skip to content

Commit

Permalink
Add more control for decoding IQ payloads
Browse files Browse the repository at this point in the history
  • Loading branch information
zinid committed Nov 13, 2016
1 parent 7e9f1a6 commit ebefd0d
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 14 deletions.
8 changes: 1 addition & 7 deletions src/ejabberd_local.erl
Expand Up @@ -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) ->
Expand Down
8 changes: 3 additions & 5 deletions src/gen_iq_handler.erl
Expand Up @@ -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} ->
Expand Down
8 changes: 7 additions & 1 deletion src/mod_delegation.erl
Expand Up @@ -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]).

Expand Down Expand Up @@ -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(
Expand Down
10 changes: 9 additions & 1 deletion src/mod_vcard.erl
Expand Up @@ -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").
Expand Down Expand Up @@ -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">>,
Expand Down

0 comments on commit ebefd0d

Please sign in to comment.