]> granicus.if.org Git - ejabberd/commitdiff
update pubsub_odbc patch
authorChristophe Romain <christophe.romain@process-one.net>
Tue, 7 Dec 2010 13:00:40 +0000 (14:00 +0100)
committerChristophe Romain <christophe.romain@process-one.net>
Tue, 7 Dec 2010 13:00:40 +0000 (14:00 +0100)
src/mod_pubsub/mod_pubsub_odbc.erl
src/mod_pubsub/pubsub_odbc.patch

index 3507091f2657fed2c2788fe3904c8e201d9f0ea6..4649aac7831bd143bac3c047de8e194082168bfd 100644 (file)
 
 %% exports for hooks
 -export([presence_probe/3,
+        caps_update/3,
         in_subscription/6,
         out_subscription/4,
         on_user_offline/3,
         remove_user/2,
-        feature_check_packet/6,
         disco_local_identity/5,
         disco_local_features/5,
         disco_local_items/5,
@@ -207,7 +207,7 @@ init([ServerHost, Opts]) ->
     ejabberd_hooks:add(anonymous_purge_hook, ServerHost, ?MODULE, remove_user, 50),
     case lists:member(?PEPNODE, Plugins) of
        true ->
-           ejabberd_hooks:add(feature_check_packet, ServerHost, ?MODULE, feature_check_packet, 75),
+           ejabberd_hooks:add(caps_update, ServerHost, ?MODULE, caps_update, 80),
            ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
            ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
            ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
@@ -257,12 +257,17 @@ init_plugins(Host, ServerHost, Opts) ->
     Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]),
     PepMapping = gen_mod:get_opt(pep_mapping, Opts, []),
     ?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
-    lists:foreach(fun(Name) ->
-                         ?DEBUG("** init ~s plugin",[Name]),
+    PluginsOK = lists:foldl(fun(Name, Acc) ->
                          Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name),
-                         Plugin:init(Host, ServerHost, Opts)
-                 end, Plugins),
-    {Plugins, TreePlugin, PepMapping}.
+                         case catch apply(Plugin, init, [Host, ServerHost, Opts]) of
+                       {'EXIT', _Error} ->
+                           Acc;
+                       _ ->
+                           ?DEBUG("** init ~s plugin",[Name]),
+                           [Name | Acc]
+                         end
+               end, [], Plugins),
+    {lists:reverse(PluginsOK), TreePlugin, PepMapping}.
 
 terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
     lists:foreach(fun(Name) ->
@@ -530,6 +535,10 @@ disco_items(Host, Node, From) ->
 %% presence hooks handling functions
 %%
 
+caps_update(#jid{luser = U, lserver = S, lresource = R} = From, To, _Features) ->
+    Pid = ejabberd_sm:get_session_pid(U, S, R),
+    presence_probe(From, To, Pid).
+
 presence_probe(#jid{luser = User, lserver = Server, lresource = Resource} = JID, JID, Pid) ->
     %%?DEBUG("presence probe self ~s@~s/~s  ~s@~s/~s",[User,Server,Resource,element(2,JID),element(3,JID),element(4,JID)]),
     presence(Server, {presence, JID, Pid}),
@@ -573,13 +582,15 @@ out_subscription(User, Server, JID, subscribed) ->
        [] -> user_resources(PUser, PServer);
        _ -> [PResource]
     end,
-    presence(Server, {presence, PUser, PServer, PResources, Owner});
+    presence(Server, {presence, PUser, PServer, PResources, Owner}),
+    true;
 out_subscription(_,_,_,_) ->
-    ok.
+    true.
 in_subscription(_, User, Server, Owner, unsubscribed, _) ->
-    unsubscribe_user(jlib:make_jid(User, Server, ""), Owner);
+    unsubscribe_user(jlib:make_jid(User, Server, ""), Owner),
+    true;
 in_subscription(_, _, _, _, _, _) ->
-    ok.
+    true.
 
 unsubscribe_user(Entity, Owner) ->
     BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
@@ -698,7 +709,7 @@ terminate(_Reason, #state{host = Host,
     ejabberd_router:unregister_route(Host),
     case lists:member(?PEPNODE, Plugins) of
        true ->
-           ejabberd_hooks:delete(feature_check_packet, ServerHost, ?MODULE, feature_check_packet, 75),
+           ejabberd_hooks:delete(caps_update, ServerHost, ?MODULE, caps_update, 80),
            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),
@@ -1732,9 +1743,11 @@ subscribe_node(Host, Node, From, JID, Configuration) ->
                    SubAttrs = case Subscription of
                                   {subscribed, SubId} ->
                                       [{"subscription", subscription_to_string(subscribed)},
-                                       {"subid", SubId}];
+                                       {"subid", SubId},
+                                       {"node",Node}];
                                   Other ->
-                                      [{"subscription", subscription_to_string(Other)}]
+                                      [{"subscription", subscription_to_string(Other)},
+                                       {"node", Node}]
                               end,
                    Fields =
                        [{"jid", jlib:jid_to_string(Subscriber)} | SubAttrs],
@@ -2998,26 +3011,11 @@ broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, Nod
            %% set the from address on the notification to the bare JID of the account owner
            %% Also, add "replyto" if entity has presence subscription to the account owner
            %% See XEP-0163 1.1 section 4.3.1
-           Sender = jlib:make_jid(LUser, LServer, ""),
-           ReplyTo = jlib:jid_to_string(Publisher),
-           StanzaToSend = add_extended_headers(Stanza, extended_headers([ReplyTo])),
-           case catch ejabberd_c2s:get_subscribed(C2SPid) of
-               Contacts when is_list(Contacts) ->
-                   lists:foreach(fun({U, S, _}) ->
-                       spawn(fun() ->
-                           case lists:member(S, ?MYHOSTS) of
-                               true ->
-                                   lists:foreach(fun(To) ->
-                                       ejabberd_router:route(Sender, jlib:make_jid(To), StanzaToSend)
-                                   end, [{U, S, R} || R <- user_resources(U, S)]);
-                               false ->
-                                   ejabberd_router:route(Sender, jlib:make_jid(U, S, ""), StanzaToSend)
-                           end
-                       end)
-                   end, Contacts);
-               _ ->
-                   ok
-           end;
+           ejabberd_c2s:broadcast(C2SPid,
+               {pep_message, binary_to_list(Node)++"+notify"},
+               _Sender = jlib:make_jid(LUser, LServer, ""),
+               _StanzaToSend = add_extended_headers(Stanza,
+                   _ReplyTo = extended_headers([jlib:jid_to_string(Publisher)])));
        _ ->
            ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza])
     end;
@@ -3573,7 +3571,7 @@ tree_action(Host, Function, Args) ->
 node_call(Type, Function, Args) ->
     ?DEBUG("node_call ~p ~p ~p",[Type, Function, Args]),
     Module = list_to_atom(?PLUGIN_PREFIX++Type),
-    case catch apply(Module, Function, Args) of
+    case apply(Module, Function, Args) of
        {result, Result} -> {result, Result};
        {error, Error} -> {error, Error};
        {'EXIT', {undef, Undefined}} ->
@@ -3736,59 +3734,6 @@ subid_shim(SubIDs) ->
 extended_headers(Jids) ->
     [{xmlelement, "address", [{"type", "replyto"}, {"jid", Jid}], []} || Jid <- Jids].
 
-
-feature_check_packet(allow, _User, Server, Pres,
-                    {#jid{lserver = LServer}, _To,
-                     {xmlelement, "message", MsgAttrs, _} = El}, in) ->
-    Host = host(Server),
-    case LServer of
-       %% If the sender Server equals Host, the message comes from the Pubsub server
-       Host ->
-           allow;
-       %% Else, the message comes from PEP
-       _ ->
-           case xml:get_subtag(El, "event") of
-               {xmlelement, _, Attrs, _} = EventEl ->
-                   case xml:get_attr_s("xmlns", Attrs) of
-                       ?NS_PUBSUB_EVENT ->
-                           case xml:get_attr_s("type", MsgAttrs) of
-                               "error" ->
-                                   %% Filter error-repsonse of PEP message
-                                   %% to avoid routing it to client
-                                   deny;
-                               _ when Pres /= undefined ->
-                                   %% Yes, sometimes Pres = undefined,
-                                   %% very rare though.
-                                   %% Seems like this is a bug: should
-                                   %% be fixed in ejabberd_s2s.erl
-                                   Feature = xml:get_path_s(
-                                               EventEl, [{elem, "items"},
-                                                         {attr, "node"}]),
-                                   case is_feature_supported(Pres, Feature) of
-                                       true ->
-                                           allow;
-                                       false ->
-                                           deny
-                                   end;
-                               _ ->
-                                   allow
-                           end;
-                       _ ->
-                           allow
-                   end;
-               _ ->
-                   allow
-           end
-    end;
-feature_check_packet(Acc, _User, _Server, _Pres, _Packet, _Direction) ->
-    Acc.
-
-is_feature_supported({xmlelement, "presence", _, Els}, Feature) ->
-    case mod_caps:read_caps(Els) of
-       nothing -> false;
-       Caps -> lists:member(Feature ++ "+notify", mod_caps:get_features(Caps))
-    end.
-
 on_user_offline(_, JID, _) ->
     {User, Server, Resource} = jlib:jid_tolower(JID),
     case ejabberd_sm:get_user_resources(User, Server) of
index 0e32e198c1f1b608031107e7eb10515ac4d7dd9a..998132f747eef0f5c366b41bace8c8bed9384b3f 100644 (file)
@@ -1,5 +1,5 @@
---- mod_pubsub.erl     2010-08-02 16:07:28.000000000 +0200
-+++ mod_pubsub_odbc.erl        2010-08-02 17:04:37.000000000 +0200
+--- mod_pubsub.erl     2010-12-07 13:54:26.000000000 +0100
++++ mod_pubsub_odbc.erl        2010-12-07 13:59:56.000000000 +0100
 @@ -42,7 +42,7 @@
  %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see
  %%% XEP-0060 section 12.18.
@@ -49,7 +49,7 @@
      init_nodes(Host, ServerHost, NodeTree, Plugins),
      State = #state{host = Host,
                server_host = ServerHost,
-@@ -277,207 +275,14 @@
+@@ -282,207 +280,14 @@
  
  init_nodes(Host, ServerHost, _NodeTree, Plugins) ->
      %% TODO, this call should be done plugin side
  send_loop(State) ->
      receive
      {presence, JID, Pid} ->
-@@ -488,17 +293,15 @@
+@@ -493,17 +298,15 @@
        %% for each node From is subscribed to
        %% and if the node is so configured, send the last published item to From
        lists:foreach(fun(PType) ->
                    true ->
                        % resource not concerned about that subscription
                        ok
-@@ -617,7 +420,8 @@
+@@ -622,7 +425,8 @@
  disco_identity(_Host, <<>>, _From) ->
      [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}];
  disco_identity(Host, Node, From) ->
            case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
                {result, _} ->
                    {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []},
-@@ -652,7 +456,8 @@
+@@ -657,7 +461,8 @@
      [?NS_PUBSUB
      | [?NS_PUBSUB++"#"++Feature || Feature <- features("pep")]];
  disco_features(Host, Node, From) ->
            case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
                {result, _} ->
                    {result, [?NS_PUBSUB
-@@ -677,7 +482,8 @@
+@@ -682,7 +487,8 @@
      Acc.
  
  disco_items(Host, <<>>, From) ->
                case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
                    {result, _} ->
                        [{xmlelement, "item",
-@@ -695,13 +501,14 @@
+@@ -700,13 +506,14 @@
                    _ -> Acc
                end
            end,
            case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of
                {result, Items} ->
                    {result, [{xmlelement, "item",
-@@ -781,10 +588,10 @@
+@@ -792,10 +599,10 @@
        lists:foreach(fun(PType) ->
            {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]),
            lists:foreach(fun
                                true ->
                                    node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]);
                                false ->
-@@ -952,7 +759,8 @@
+@@ -963,7 +770,8 @@
                            sub_el = SubEl} = IQ ->
                            {xmlelement, _, QAttrs, _} = SubEl,
                            Node = xml:get_attr_s("node", QAttrs),
                                      {result, IQRes} ->
                                          jlib:iq_to_xml(
                                            IQ#iq{type = result,
-@@ -1065,7 +873,7 @@
+@@ -1076,7 +884,7 @@
                                    [] ->
                                        ["leaf"]; %% No sub-nodes: it's a leaf node
                                    _ ->
                                            {result, []} -> ["collection"];
                                            {result, _} -> ["leaf", "collection"];
                                            _ -> []
-@@ -1081,8 +889,9 @@
+@@ -1092,8 +900,9 @@
                            [];
                        true ->
                            [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} |
                                       end, features(Type))]
                    end,
                %% TODO: add meta-data info (spec section 5.4)
-@@ -1111,8 +920,9 @@
+@@ -1122,8 +931,9 @@
                {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []},
                {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []},
                {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++
             end, features(Host, Node))};
          <<?NS_COMMANDS>> ->
              command_disco_info(Host, Node, From);
-@@ -1122,7 +932,7 @@
+@@ -1133,7 +943,7 @@
            node_disco_info(Host, Node, From)
      end.
  
      case tree_action(Host, get_subnodes, [Host, <<>>, From]) of
        Nodes when is_list(Nodes) ->
            {result, lists:map(
-@@ -1139,23 +949,24 @@
+@@ -1150,23 +960,24 @@
        Other ->
            Other
      end;
                            end,
                        Nodes = lists:map(
                                fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) ->
-@@ -1173,7 +984,7 @@
+@@ -1184,7 +995,7 @@
                                    {result, Name} = node_call(Type, get_item_name, [Host, Node, RN]),
                                    {xmlelement, "item", [{"jid", Host}, {"name", Name}], []}
                                end, NodeItems),
                end,
            case transaction(Host, Node, Action, sync_dirty) of
                {result, {_, Result}} -> {result, Result};
-@@ -1284,7 +1095,8 @@
+@@ -1295,7 +1106,8 @@
                        (_, Acc) ->
                            Acc
                        end, [], xml:remove_cdata(Els)),
                {get, "subscriptions"} ->
                    get_subscriptions(Host, Node, From, Plugins);
                {get, "affiliations"} ->
-@@ -1307,7 +1119,9 @@
+@@ -1318,7 +1130,9 @@
  
  iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
      {xmlelement, _, _, SubEls} = SubEl,
      case Action of
        [{xmlelement, Name, Attrs, Els}] ->
            Node = string_to_node(xml:get_attr_s("node", Attrs)),
-@@ -1437,7 +1251,8 @@
+@@ -1448,7 +1262,8 @@
                    _          -> []
                end
        end,
                     sync_dirty) of
        {result, Res} -> Res;
        Err        -> Err
-@@ -1476,7 +1291,7 @@
+@@ -1487,7 +1302,7 @@
  
  %%% authorization handling
  
      Lang = "en", %% TODO fix
      Stanza = {xmlelement, "message",
              [],
-@@ -1505,7 +1320,7 @@
+@@ -1516,7 +1331,7 @@
                  [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]},
      lists:foreach(fun(Owner) ->
        ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza)
  
  find_authorization_response(Packet) ->
      {xmlelement, _Name, _Attrs, Els} = Packet,
-@@ -1569,8 +1384,8 @@
+@@ -1580,8 +1395,8 @@
                        "true" -> true;
                        _ -> false
                    end,
                             {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]),
                             if
                                 not IsApprover ->
-@@ -1769,7 +1584,7 @@
+@@ -1780,7 +1595,7 @@
            Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
                      [{xmlelement, "create", nodeAttr(Node),
                        []}]}],
                {result, {NodeId, SubsByDepth, {Result, broadcast}}} ->
                    broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth),
                    case Result of
-@@ -1872,7 +1687,7 @@
+@@ -1883,7 +1698,7 @@
  %%<li>The node does not exist.</li>
  %%</ul>
  subscribe_node(Host, Node, From, JID, Configuration) ->
        {result, GoodSubOpts} -> GoodSubOpts;
        _ -> invalid
      end,
-@@ -1880,7 +1695,7 @@
+@@ -1891,7 +1706,7 @@
                     error -> {"", "", ""};
                     J -> jlib:jid_tolower(J)
                 end,
                    Features = features(Type),
                    SubscribeFeature = lists:member("subscribe", Features),
                    OptionsFeature = lists:member("subscription-options", Features),
-@@ -1889,6 +1704,7 @@
+@@ -1900,6 +1715,7 @@
                    AccessModel = get_option(Options, access_model),
                    SendLast = get_option(Options, send_last_published_item),
                    AllowedGroups = get_option(Options, roster_groups_allowed, []),
                    {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups),
                    if
                        not SubscribeFeature ->
-@@ -2218,7 +2034,7 @@
+@@ -2231,7 +2047,7 @@
  %% <p>The permission are not checked in this function.</p>
  %% @todo We probably need to check that the user doing the query has the right
  %% to read the items.
      MaxItems =
        if
            SMaxItems == "" -> get_max_items_node(Host);
-@@ -2232,12 +2048,13 @@
+@@ -2245,12 +2061,13 @@
        {error, Error} ->
            {error, Error};
        _ ->
                     {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups),
                     if
                         not RetreiveFeature ->
-@@ -2250,11 +2067,11 @@
+@@ -2263,11 +2080,11 @@
                             node_call(Type, get_items,
                                       [NodeId, From,
                                        AccessModel, PresenceSubscription, RosterGroup,
                    SendItems = case ItemIDs of
                        [] -> 
                            Items;
-@@ -2267,7 +2084,8 @@
+@@ -2280,7 +2097,8 @@
                    %% number of items sent to MaxItems:
                    {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
                                [{xmlelement, "items", nodeAttr(Node),
                Error ->
                    Error
            end
-@@ -2289,10 +2107,15 @@
+@@ -2302,10 +2120,15 @@
        Error -> Error
      end.
  get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) ->
  
  
  %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any()
-@@ -2305,16 +2128,27 @@
+@@ -2318,16 +2141,27 @@
  %% @doc <p>Resend the items of a node to the user.</p>
  %% @todo use cache-last-item feature
  send_items(Host, Node, NodeId, Type, LJID, last) ->
  send_items(Host, Node, NodeId, Type, LJID, Number) ->
      ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of
        {result, []} -> 
-@@ -2440,7 +2274,8 @@
+@@ -2453,7 +2287,8 @@
        error ->
            {error, ?ERR_BAD_REQUEST};
        _ ->
                        case lists:member(Owner, Owners) of
                            true ->
                                OwnerJID = jlib:make_jid(Owner),
-@@ -2450,24 +2285,7 @@
+@@ -2463,24 +2298,7 @@
                                    end,
                                lists:foreach(
                                    fun({JID, Affiliation}) ->
                                    end, FilteredEntities),
                                {result, []};
                            _ ->
-@@ -2520,11 +2338,11 @@
+@@ -2533,11 +2351,11 @@
      end.
  
  read_sub(Subscriber, Node, NodeID, SubID, Lang) ->
            OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)},
                                                 {"subid", SubID}|nodeAttr(Node)],
                         [XdataEl]},
-@@ -2550,7 +2368,7 @@
+@@ -2563,7 +2381,7 @@
      end.
  
  set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
        {result, GoodSubOpts} -> GoodSubOpts;
        _ -> invalid
      end,
-@@ -2579,7 +2397,7 @@
+@@ -2592,7 +2410,7 @@
  write_sub(_Subscriber, _NodeID, _SubID, invalid) ->
      {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")};
  write_sub(Subscriber, NodeID, SubID, Options) ->
        {error, notfound} ->
            {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
        {result, _} ->
-@@ -2747,8 +2565,8 @@
+@@ -2760,8 +2578,8 @@
                                     {"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]},
                ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza)
            end,
                                true ->
                                    Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) ->
  
-@@ -3103,7 +2921,7 @@
+@@ -3116,7 +2934,7 @@
                        {Depth, [{N, get_node_subs(N)} || N <- Nodes]}
            end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
        end,
        {result, CollSubs} -> CollSubs;
        _ -> []
      end.
-@@ -3117,9 +2935,9 @@
+@@ -3130,9 +2948,9 @@
  
  get_options_for_subs(NodeID, Subs) ->
      lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
                            _ -> Acc
                        end;
                    (_, Acc) ->
-@@ -3323,6 +3141,30 @@
+@@ -3321,6 +3139,30 @@
            Result
      end.
  
  %% @spec (Host, Options) -> MaxItems
  %%     Host = host()
  %%     Options = [Option]
-@@ -3719,7 +3561,13 @@
+@@ -3717,7 +3559,13 @@
  tree_action(Host, Function, Args) ->
      ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
      Fun = fun() -> tree_call(Host, Function, Args) end,
  
  %% @doc <p>node plugin call.</p>
  node_call(Type, Function, Args) ->
-@@ -3739,13 +3587,13 @@
+@@ -3737,13 +3585,13 @@
  
  node_action(Host, Type, Function, Args) ->
      ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
                        case tree_call(Host, get_node, [Host, Node]) of
                            N when is_record(N, pubsub_node) ->
                                case Action(N) of
-@@ -3757,13 +3605,19 @@
+@@ -3755,13 +3603,19 @@
                                Error
                        end
                end, Trans).
        {result, Result} -> {result, Result};
        {error, Error} -> {error, Error};
        {atomic, {result, Result}} -> {result, Result};
-@@ -3771,6 +3625,15 @@
+@@ -3769,6 +3623,15 @@
        {aborted, Reason} ->
            ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
            {error, ?ERR_INTERNAL_SERVER_ERROR};
        {'EXIT', Reason} ->
            ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
            {error, ?ERR_INTERNAL_SERVER_ERROR};
-@@ -3779,6 +3642,17 @@
+@@ -3777,6 +3640,17 @@
            {error, ?ERR_INTERNAL_SERVER_ERROR}
      end.