]> granicus.if.org Git - ejabberd/commitdiff
better hadling of presence in mod_caps
authorChristophe Romain <christophe.romain@process-one.net>
Fri, 10 Apr 2009 07:36:17 +0000 (07:36 +0000)
committerChristophe Romain <christophe.romain@process-one.net>
Fri, 10 Apr 2009 07:36:17 +0000 (07:36 +0000)
SVN Revision: 2012

ChangeLog
src/ejabberd_c2s.erl
src/mod_caps.erl
src/mod_pubsub/mod_pubsub.erl

index 6c41ea9d493180257fbf576b7b688e968cd8e7ca..c5ccd1a474f3eadf61e26e1c6746ee7ae2fe6019 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-04-10  Christophe Romain <christophe.romain@process-one.net>
+
+       * src/mod_caps.erl: Better handling of presence hook and caps clean
+       * src/ejabberd_c2s.erl: Likewise
+       * src/mod_pubsub/mod_pubsub.erl: Likewise
+
+       * src/mod_pubsub/mod_pubsub.erl: Improve invalid-payload check, send
+       last published item to new resource only, thread message sending.
+       (from r2005 commit)
+
 2009-04-09  Badlop  <badlop@process-one.net>
 
        * src/msgs/pl.po: Fix some translations (thanks to Andrzej Smyk)
index 05bbdd07080b34bcb0b40f2cf0803057d8d3c150..79242dda49e95ab1979b935783b3a698c594a7e6 100644 (file)
@@ -1126,16 +1126,6 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
                            allow ->
                                LFrom = jlib:jid_tolower(From),
                                LBFrom = jlib:jid_remove_resource(LFrom),
-                               %% Note contact availability
-                               case xml:get_attr_s("type", Attrs) of
-                                   "unavailable" ->
-                                       %mod_caps:clear_caps(From);
-                                       % caps clear disabled cause it breaks things
-                                       ok;
-                                   _ ->
-                                       Caps = mod_caps:read_caps(Els),
-                                       mod_caps:note_caps(StateData#state.server, From, Caps)
-                               end,
                                case ?SETS:is_element(
                                        LFrom, StateData#state.pres_a) orelse
                                    ?SETS:is_element(
index 1eca49aab14907bd8fcf3d1cb60c959b59d6112b..2ccdd435a7b9d779664e9e809f3caf4ff96284b3 100644 (file)
         code_change/3
        ]).
 
+%% hook handlers
+-export([receive_packet/3,
+        receive_packet/4]).
+
 -include("ejabberd.hrl").
 -include("jlib.hrl").
 
@@ -165,6 +169,34 @@ stop(Host) ->
     Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
     gen_server:call(Proc, stop).
 
+receive_packet(From, To, {xmlelement, "presence", Attrs, Els}) ->
+    case xml:get_attr_s("type", Attrs) of
+    "probe" ->
+       ok;
+    "error" ->
+       ok;
+    "invisible" ->
+       ok;
+    "subscribe" ->
+       ok;
+    "subscribed" ->
+       ok;
+    "unsubscribe" ->
+       ok;
+    "unsubscribed" ->
+       ok;
+    "unavailable" ->
+       mod_caps:clear_caps(From);
+    _ ->
+       Caps = mod_caps:read_caps(Els),
+       mod_caps:note_caps(To#jid.lserver, From, Caps)
+    end;
+receive_packet(_, _, _) ->
+    ok.
+
+receive_packet(_JID, From, To, Packet) ->
+    receive_packet(From, To, Packet).
+
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
@@ -181,6 +213,8 @@ init([Host, _Opts]) ->
                         {type, bag},
                         {attributes, record_info(fields, user_caps_resources)}]),
     mnesia:delete_table(user_caps_default),
+    ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, receive_packet, 30),
+    ejabberd_hooks:add(s2s_receive_packet, Host, ?MODULE, receive_packet, 30),
     {ok, #state{host = Host}}.
 
 maybe_get_features(#caps{node = Node, version = Version, exts = Exts}) ->
@@ -359,7 +393,10 @@ handle_disco_response(From, To, IQ) ->
 handle_info(_Info, State) ->
     {noreply, State}.
 
-terminate(_Reason, _State) ->
+terminate(_Reason, State) ->
+    Host = State#state.host,
+    ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, receive_packet, 30),
+    ejabberd_hooks:delete(s2s_receive_packet, Host, ?MODULE, receive_packet, 30),
     ok.
 
 code_change(_OldVsn, State, _Extra) ->
index fcb918bb8a714636cce817a2f5c39d7cced6b378..bcbb2bfe4bf2471a779c96a5ee2631f4ad7e0fcb 100644 (file)
@@ -157,6 +157,7 @@ init([ServerHost, Opts]) ->
     ?DEBUG("pubsub init ~p ~p",[ServerHost,Opts]),
     Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"),
     Access = gen_mod:get_opt(access_createnode, Opts, all),
+    IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
     mod_disco:register_feature(ServerHost, ?NS_PUBSUB),
     ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
@@ -164,14 +165,8 @@ init([ServerHost, Opts]) ->
     ejabberd_hooks:add(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50),
     ejabberd_hooks:add(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50),
     ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50),
-    IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
-    lists:foreach(
-      fun({NS,Mod,Fun}) ->
-             gen_iq_handler:add_iq_handler(
-               Mod, ServerHost, NS, ?MODULE, Fun, IQDisc)
-      end,
-      [{?NS_PUBSUB, ejabberd_sm, iq_sm},
-       {?NS_PUBSUB_OWNER, ejabberd_sm, iq_sm}]),
+    gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB, ?MODULE, iq_sm, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER, ?MODULE, iq_sm, IQDisc),
     ejabberd_router:register_route(Host),
     {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
     case lists:member("pep", Plugins) of
@@ -179,13 +174,8 @@ init([ServerHost, Opts]) ->
            ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75),
            ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75),
            ejabberd_hooks:add(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75),
-           lists:foreach(
-             fun({NS,Mod,Fun}) ->
-                     gen_iq_handler:add_iq_handler(
-                       Mod, ServerHost, NS, ?MODULE, Fun, IQDisc)
-             end,
-             [{?NS_PUBSUB, ejabberd_local, iq_local},
-              {?NS_PUBSUB_OWNER, ejabberd_local, iq_local}]);
+           gen_iq_handler:add_iq_handler(ejabberd_local, ServerHost, ?NS_PUBSUB, ?MODULE, iq_local, IQDisc),
+           gen_iq_handler:add_iq_handler(ejabberd_local, ServerHost, ?NS_PUBSUB_OWNER, ?MODULE, iq_local, IQDisc);
        false ->
            ok
     end,
@@ -613,21 +603,24 @@ terminate(_Reason, #state{host = Host,
                          plugins = Plugins}) ->
     terminate_plugins(Host, ServerHost, Plugins, TreePlugin),
     ejabberd_router:unregister_route(Host),
-    ejabberd_hooks:delete(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75),
-    ejabberd_hooks:delete(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75),
-    ejabberd_hooks:delete(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75),
+    case lists:member("pep", Plugins) of
+       true ->
+           ejabberd_hooks:delete(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75),
+           ejabberd_hooks:delete(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75),
+           ejabberd_hooks:delete(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75),
+           gen_iq_handler:remove_iq_handler(ejabberd_local, ServerHost, ?NS_PUBSUB),
+           gen_iq_handler:remove_iq_handler(ejabberd_local, ServerHost, ?NS_PUBSUB_OWNER);
+       false ->
+           ok
+    end,
     ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
     ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
     ejabberd_hooks:delete(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 50),
     ejabberd_hooks:delete(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50),
     ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50),
-    lists:foreach(fun({NS,Mod}) ->
-                         gen_iq_handler:remove_iq_handler(Mod, ServerHost, NS)
-                 end, [{?NS_PUBSUB, ejabberd_local},
-                       {?NS_PUBSUB_OWNER, ejabberd_local},
-                       {?NS_PUBSUB, ejabberd_sm},
-                       {?NS_PUBSUB_OWNER, ejabberd_sm}]),
+    gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB),
+    gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER),
     mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB),
     ok.
 
@@ -1553,12 +1546,12 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
                        PayloadSize > PayloadMaxSize ->
                            %% Entity attempts to publish very large payload
                            {error, extended_error(?ERR_NOT_ACCEPTABLE, "payload-too-big")};
-                       PayloadCount =/= 1 ->
-                           %% Entity attempts to publish item with multiple payload elements
-                           {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")};
-                       Payload == "" -> %% TODO better use PayloadSize == 0 ?
+                       PayloadCount == 0 ->
                            %% Publisher attempts to publish to payload node with no payload
                            {error, extended_error(?ERR_BAD_REQUEST, "payload-required")};
+                       PayloadCount > 1 ->
+                           %% Entity attempts to publish item with multiple payload elements
+                           {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")};
                        (DeliverPayloads == 0) and (PersistItems == 0) and (PayloadSize > 0) ->
                            %% Publisher attempts to publish to transient notification node with item
                            {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")};