aboutsummaryrefslogtreecommitdiff
path: root/src/gen_iq_handler.erl
diff options
context:
space:
mode:
authorMickael Remond <mremond@process-one.net>2016-12-01 15:05:09 +0100
committerMickael Remond <mremond@process-one.net>2016-12-01 15:05:09 +0100
commit309fd56fb4bbb82215e4e9873eeb677e49f804de (patch)
tree3993dc3b1c9d81c18163f853760e678e3d3337d1 /src/gen_iq_handler.erl
parentMerge branch 'master' of github.com:processone/ejabberd (diff)
parentFixes pt-br translation (thanks to Rodrigues)(#1393) (diff)
Merge branch 'master' of github.com:processone/ejabberd
Diffstat (limited to 'src/gen_iq_handler.erl')
-rw-r--r--src/gen_iq_handler.erl54
1 files changed, 45 insertions, 9 deletions
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index c2b4252c9..4a7a03c27 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -40,13 +40,14 @@
-include("ejabberd.hrl").
-include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
-record(state, {host, module, function}).
-type component() :: ejabberd_sm | ejabberd_local.
-type type() :: no_queue | one_queue | pos_integer() | parallel.
-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
+-export_type([opts/0]).
%%====================================================================
%% API
@@ -59,6 +60,8 @@ start_link(Host, Module, Function) ->
gen_server:start_link(?MODULE, [Host, Module, Function],
[]).
+-spec add_iq_handler(module(), binary(), binary(), module(), atom(), type()) -> any().
+
add_iq_handler(Component, Host, NS, Module, Function,
Type) ->
case Type of
@@ -124,14 +127,47 @@ handle(Host, Module, Function, Opts, From, To, IQ) ->
-spec process_iq(binary(), atom(), atom(), jid(), jid(), iq()) -> any().
-process_iq(_Host, Module, Function, From, To, IQ) ->
- case catch Module:Function(From, To, IQ) of
- {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
- ResIQ ->
- if ResIQ /= ignore ->
- ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ));
- true -> ok
- end
+process_iq(_Host, Module, Function, From, To, IQ0) ->
+ IQ = xmpp:set_from_to(IQ0, From, To),
+ try
+ ResIQ = case erlang:function_exported(Module, Function, 1) of
+ true ->
+ process_iq(Module, Function, IQ);
+ false ->
+ process_iq(Module, Function, From, To,
+ jlib:iq_query_info(xmpp:encode(IQ)))
+ end,
+ if ResIQ /= ignore ->
+ ejabberd_router:route(To, From, ResIQ);
+ true ->
+ ok
+ end
+ catch E:R ->
+ ?ERROR_MSG("failed to process iq:~n~s~nReason = ~p",
+ [xmpp:pp(IQ), {E, {R, erlang:get_stacktrace()}}]),
+ Txt = <<"Module failed to handle the query">>,
+ Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
+ ejabberd_router:route_error(To, From, IQ, Err)
+ end.
+
+-spec process_iq(module(), atom(), iq()) -> ignore | iq().
+process_iq(Module, Function, #iq{lang = Lang, sub_els = [El]} = IQ) ->
+ try
+ 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} ->
+ Txt = xmpp:format_error(Why),
+ xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang))
+ end.
+
+-spec process_iq(module(), atom(), jid(), jid(), term()) -> iq().
+process_iq(Module, Function, From, To, IQ) ->
+ case Module:Function(From, To, IQ) of
+ ignore -> ignore;
+ ResIQ -> xmpp:decode(jlib:iq_to_xml(ResIQ), ?NS_CLIENT, [ignore_els])
end.
-spec check_type(type()) -> type().