]> granicus.if.org Git - ejabberd/commitdiff
Reduce IQ handler code copying
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 9 May 2018 07:30:00 +0000 (10:30 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 9 May 2018 07:30:00 +0000 (10:30 +0300)
src/ejabberd_local.erl
src/ejabberd_router.erl
src/ejabberd_sm.erl
src/gen_iq_handler.erl
src/mod_muc.erl

index 9d75c69f2e74eb4733c7424af70b1d4a4375a4b8..9f250fab37055ea6f8f049611318deafa5398b76 100644 (file)
 %% API
 -export([start/0, start_link/0]).
 
--export([route/1, process_iq/1,
+-export([route/1,
         get_features/1,
-        register_iq_handler/4,
-        unregister_iq_handler/2,
         bounce_resource_packet/1,
         host_up/1, host_down/1]).
 
@@ -54,8 +52,6 @@
 
 -record(state, {}).
 
--define(IQTABLE, local_iqtable).
-
 %%====================================================================
 %% API
 %%====================================================================
@@ -72,30 +68,6 @@ start_link() ->
     gen_server:start_link({local, ?MODULE}, ?MODULE, [],
                          []).
 
--spec process_iq(iq()) -> any().
-process_iq(#iq{to = To, type = T, lang = Lang, sub_els = [El]} = Packet)
-  when T == get; T == set ->
-    XMLNS = xmpp:get_ns(El),
-    Host = To#jid.lserver,
-    case ets:lookup(?IQTABLE, {Host, XMLNS}) of
-       [{_, Module, Function}] ->
-           gen_iq_handler:handle(Host, Module, Function, Packet);
-       [] ->
-           Txt = <<"No module is handling this query">>,
-           Err = xmpp:err_service_unavailable(Txt, Lang),
-           ejabberd_router:route_error(Packet, Err)
-    end;
-process_iq(#iq{type = T, lang = Lang, sub_els = SubEls} = Packet)
-  when T == get; T == set ->
-    Txt = case SubEls of
-             [] -> <<"No child elements found">>;
-             _ -> <<"Too many child elements">>
-         end,
-    Err = xmpp:err_bad_request(Txt, Lang),
-    ejabberd_router:route_error(Packet, Err);
-process_iq(#iq{type = T}) when T == result; T == error ->
-    ok.
-
 -spec route(stanza()) -> any().
 route(Packet) ->
     try do_route(Packet)
@@ -112,15 +84,6 @@ route_iq(IQ, Fun) ->
 route_iq(IQ, Fun, Timeout) ->
     ejabberd_router:route_iq(IQ, Fun, undefined, Timeout).
 
--spec register_iq_handler(binary(), binary(), module(), function()) -> ok.
-register_iq_handler(Host, XMLNS, Module, Fun) ->
-    gen_server:cast(?MODULE,
-                   {register_iq_handler, Host, XMLNS, Module, Fun}).
-
--spec unregister_iq_handler(binary(), binary()) -> ok.
-unregister_iq_handler(Host, XMLNS) ->
-    gen_server:cast(?MODULE, {unregister_iq_handler, Host, XMLNS}).
-
 -spec bounce_resource_packet(stanza()) -> ok | stop.
 bounce_resource_packet(#presence{to = #jid{lresource = <<"">>}}) ->
     ok;
@@ -135,12 +98,7 @@ bounce_resource_packet(Packet) ->
 
 -spec get_features(binary()) -> [binary()].
 get_features(Host) ->
-    get_features(ets:next(?IQTABLE, {Host, <<"">>}), Host, []).
-
-get_features({Host, XMLNS}, Host, XMLNSs) ->
-    get_features(ets:next(?IQTABLE, {Host, XMLNS}), Host, [XMLNS|XMLNSs]);
-get_features(_, _, XMLNSs) ->
-    XMLNSs.
+    gen_iq_handler:get_features(?MODULE, Host).
 
 %%====================================================================
 %% gen_server callbacks
@@ -151,23 +109,13 @@ init([]) ->
     lists:foreach(fun host_up/1, ?MYHOSTS),
     ejabberd_hooks:add(host_up, ?MODULE, host_up, 10),
     ejabberd_hooks:add(host_down, ?MODULE, host_down, 100),
-    catch ets:new(?IQTABLE, [named_table, public, ordered_set,
-                            {read_concurrency, true}]),
+    gen_iq_handler:start(?MODULE),
     update_table(),
     {ok, #state{}}.
 
 handle_call(_Request, _From, State) ->
     Reply = ok, {reply, Reply, State}.
 
-handle_cast({register_iq_handler, Host, XMLNS, Module, Function},
-           State) ->
-    ets:insert(?IQTABLE,
-              {{Host, XMLNS}, Module, Function}),
-    {noreply, State};
-handle_cast({unregister_iq_handler, Host, XMLNS},
-           State) ->
-    ets:delete(?IQTABLE, {Host, XMLNS}),
-    {noreply, State};
 handle_cast(_Msg, State) -> {noreply, State}.
 
 handle_info({route, Packet}, State) ->
@@ -197,7 +145,7 @@ do_route(Packet) ->
     if To#jid.luser /= <<"">> ->
            ejabberd_sm:route(Packet);
        is_record(Packet, iq), To#jid.lresource == <<"">> ->
-           process_iq(Packet);
+           gen_iq_handler:handle(?MODULE, Packet);
        Type == result; Type == error ->
            ok;
        true ->
index feb79549d74d152ee5719be901e1efafdd404032..f49e94194869473f788718a0c7d85602ea2b076e 100644 (file)
@@ -306,12 +306,8 @@ is_my_host(Domain) ->
     end.
 
 -spec process_iq(iq()) -> any().
-process_iq(#iq{to = To} = IQ) ->
-    if To#jid.luser == <<"">> ->
-           ejabberd_local:process_iq(IQ);
-       true ->
-           ejabberd_sm:process_iq(IQ)
-    end.
+process_iq(IQ) ->
+    gen_iq_handler:handle(IQ).
 
 -spec config_reloaded() -> ok.
 config_reloaded() ->
index 8a9893437cf71fe2c36068fd33b770e64ec416de..e35f31079841908fa34b79d5ccf06c3ab17e9fde 100644 (file)
@@ -39,7 +39,6 @@
         stop/0,
         route/1,
         route/2,
-        process_iq/1,
         open_session/5,
         open_session/6,
         close_session/4,
@@ -58,8 +57,6 @@
         get_vh_session_list/1,
         get_vh_session_number/1,
         get_vh_by_backend/1,
-        register_iq_handler/4,
-        unregister_iq_handler/2,
         force_update_presence/1,
         connected_users/0,
         connected_users_number/0,
@@ -397,17 +394,6 @@ get_vh_session_number(Server) ->
     Mod = get_sm_backend(LServer),
     length(online(get_sessions(Mod, LServer))).
 
--spec register_iq_handler(binary(), binary(), atom(), atom()) -> ok.
-
-register_iq_handler(Host, XMLNS, Module, Fun) ->
-    ?GEN_SERVER:cast(?MODULE,
-                   {register_iq_handler, Host, XMLNS, Module, Fun}).
-
--spec unregister_iq_handler(binary(), binary()) -> ok.
-
-unregister_iq_handler(Host, XMLNS) ->
-    ?GEN_SERVER:cast(?MODULE, {unregister_iq_handler, Host, XMLNS}).
-
 %% Why the hell do we have so many similar kicks?
 c2s_handle_info(#{lang := Lang} = State, replaced) ->
     State1 = State#{replaced => true},
@@ -437,7 +423,7 @@ init([]) ->
     init_cache(),
     lists:foreach(fun(Mod) -> Mod:init() end, get_sm_backends()),
     clean_cache(),
-    ets:new(sm_iqtable, [named_table, public, {read_concurrency, true}]),
+    gen_iq_handler:start(?MODULE),
     ejabberd_hooks:add(host_up, ?MODULE, host_up, 50),
     ejabberd_hooks:add(host_down, ?MODULE, host_down, 60),
     ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 50),
@@ -448,15 +434,6 @@ init([]) ->
 handle_call(_Request, _From, State) ->
     Reply = ok, {reply, Reply, State}.
 
-handle_cast({register_iq_handler, Host, XMLNS, Module, Function},
-           State) ->
-    ets:insert(sm_iqtable,
-              {{Host, XMLNS}, Module, Function}),
-    {noreply, State};
-handle_cast({unregister_iq_handler, Host, XMLNS},
-           State) ->
-    ets:delete(sm_iqtable, {Host, XMLNS}),
-    {noreply, State};
 handle_cast(_Msg, State) -> {noreply, State}.
 
 handle_info({route, Packet}, State) ->
@@ -664,7 +641,7 @@ do_route(#message{to = #jid{lresource = <<"">>}, type = T} = Packet) ->
     end;
 do_route(#iq{to = #jid{lresource = <<"">>}} = Packet) ->
     ?DEBUG("processing IQ to bare JID:~n~s", [xmpp:pp(Packet)]),
-    process_iq(Packet);
+    gen_iq_handler:handle(?MODULE, Packet);
 do_route(Packet) ->
     ?DEBUG("processing packet to full JID:~n~s", [xmpp:pp(Packet)]),
     To = xmpp:get_to(Packet),
@@ -849,31 +826,6 @@ get_max_user_sessions(LUser, Host) ->
     end.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--spec process_iq(iq()) -> any().
-process_iq(#iq{to = To, type = T, lang = Lang, sub_els = [El]} = Packet)
-  when T == get; T == set ->
-    XMLNS = xmpp:get_ns(El),
-    Host = To#jid.lserver,
-    case ets:lookup(sm_iqtable, {Host, XMLNS}) of
-       [{_, Module, Function}] ->
-           gen_iq_handler:handle(Host, Module, Function, Packet);
-       [] ->
-           Txt = <<"No module is handling this query">>,
-           Err = xmpp:err_service_unavailable(Txt, Lang),
-           ejabberd_router:route_error(Packet, Err)
-    end;
-process_iq(#iq{type = T, lang = Lang, sub_els = SubEls} = Packet)
-  when T == get; T == set ->
-    Txt = case SubEls of
-             [] -> <<"No child elements found">>;
-             _ -> <<"Too many child elements">>
-         end,
-    Err = xmpp:err_bad_request(Txt, Lang),
-    ejabberd_router:route_error(Packet, Err);
-process_iq(#iq{}) ->
-    ok.
-
 -spec force_update_presence({binary(), binary()}) -> ok.
 
 force_update_presence({LUser, LServer}) ->
index 0982a9f46714c8c600bcfa1ba2a398d8f23fd52c..15155ac1a1976afbd46c0b9ddd429a00989dde20 100644 (file)
@@ -30,9 +30,9 @@
 -behaviour(ejabberd_config).
 
 %% API
--export([add_iq_handler/5, remove_iq_handler/3, handle/4,
-        process_iq/4, check_type/1, transform_module_options/1,
-        opt_type/1]).
+-export([add_iq_handler/5, remove_iq_handler/3, handle/1, handle/2,
+        check_type/1, transform_module_options/1,
+        opt_type/1, start/1, get_features/2]).
 %% Deprecated functions
 -export([add_iq_handler/6, handle/5, iqdisc/1]).
 -deprecated([{add_iq_handler, 6}, {handle, 5}, {iqdisc, 1}]).
 %%====================================================================
 %% API
 %%====================================================================
--spec add_iq_handler(module(), binary(), binary(), module(), atom()) -> ok.
+-spec start(component()) -> ok.
+start(Component) ->
+    catch ets:new(Component, [named_table, public, ordered_set,
+                             {read_concurrency, true},
+                             {heir, erlang:group_leader(), none}]),
+    ok.
+
+-spec add_iq_handler(component(), binary(), binary(), module(), atom()) -> ok.
 add_iq_handler(Component, Host, NS, Module, Function) ->
-    Component:register_iq_handler(Host, NS, Module, Function).
+    ets:insert(Component, {{Host, NS}, Module, Function}),
+    ok.
 
 -spec remove_iq_handler(component(), binary(), binary()) -> ok.
 remove_iq_handler(Component, Host, NS) ->
-    Component:unregister_iq_handler(Host, NS).
-
--spec handle(binary(), atom(), atom(), iq()) -> any().
-handle(Host, Module, Function, IQ) ->
-    process_iq(Host, Module, Function, IQ).
+    ets:delete(Component, {Host, NS}),
+    ok.
+
+-spec handle(iq()) -> ok.
+handle(#iq{to = To} = IQ) ->
+    Component = case To#jid.luser of
+                   <<"">> -> ejabberd_local;
+                   _ -> ejabberd_sm
+               end,
+    handle(Component, IQ).
+
+-spec handle(component(), iq()) -> ok.
+handle(Component,
+       #iq{to = To, type = T, lang = Lang, sub_els = [El]} = Packet)
+  when T == get; T == set ->
+    XMLNS = xmpp:get_ns(El),
+    Host = To#jid.lserver,
+    case ets:lookup(Component, {Host, XMLNS}) of
+       [{_, Module, Function}] ->
+           process_iq(Host, Module, Function, Packet);
+       [] ->
+           Txt = <<"No module is handling this query">>,
+           Err = xmpp:err_service_unavailable(Txt, Lang),
+           ejabberd_router:route_error(Packet, Err)
+    end;
+handle(_, #iq{type = T, lang = Lang, sub_els = SubEls} = Packet)
+  when T == get; T == set ->
+    Txt = case SubEls of
+             [] -> <<"No child elements found">>;
+             _ -> <<"Too many child elements">>
+         end,
+    Err = xmpp:err_bad_request(Txt, Lang),
+    ejabberd_router:route_error(Packet, Err);
+handle(_, #iq{type = T}) when T == result; T == error ->
+    ok.
+
+-spec get_features(component(), binary()) -> [binary()].
+get_features(Component, Host) ->
+    get_features(Component, ets:next(Component, {Host, <<"">>}), Host, []).
+
+get_features(Component, {Host, XMLNS}, Host, XMLNSs) ->
+    get_features(Component,
+                ets:next(Component, {Host, XMLNS}), Host, [XMLNS|XMLNSs]);
+get_features(_, _, _, XMLNSs) ->
+    XMLNSs.
 
 -spec process_iq(binary(), atom(), atom(), iq()) -> any().
 process_iq(_Host, Module, Function, IQ) ->
@@ -139,4 +187,4 @@ add_iq_handler(Component, Host, NS, Module, Function, _Type) ->
 
 -spec handle(binary(), atom(), atom(), any(), iq()) -> any().
 handle(Host, Module, Function, _Opts, IQ) ->
-    handle(Host, Module, Function, IQ).
+    process_iq(Host, Module, Function, IQ).
index 2c10435b61b711bfb919a59aeeada2f7abf01d53..5a52c9bdddbabdea0c48cee7101b38518b543cac 100644 (file)
@@ -399,7 +399,7 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
 do_route1(_Host, _ServerHost, _Access, _HistorySize, _RoomShaper,
          _From, #jid{luser = <<"">>, lresource = <<"">>} = _To,
          #iq{} = IQ, _DefRoomOpts, _QueueType) ->
-    ejabberd_local:process_iq(IQ);
+    ejabberd_router:process_iq(IQ);
 do_route1(Host, ServerHost, Access, _HistorySize, _RoomShaper,
          From, #jid{luser = <<"">>, lresource = <<"">>} = _To,
          #message{lang = Lang, body = Body, type = Type} = Packet, _, _) ->