diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index 9e19c5de1..39c0f51e1 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -2963,7 +2963,7 @@ event_stanza_withmoreels(Els, MoreEls) ->
%%%%%% broadcast functions
-broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, _From, Payload) ->
+broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, From, Payload) ->
%broadcast(Host, Node, NodeId, Options, none, true, 'items', ItemEls)
case get_collection_subscriptions(Host, Node) of
[] ->
@@ -2977,7 +2977,7 @@ broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, _From
Stanza = event_stanza(
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children =
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = itemAttr(ItemId), children = Content}]}]),
- broadcast_stanza(Host, Node, NodeId, Type, Options, SubsByDepth, items, Stanza, true),
+ broadcast_stanza(Host, From, Node, NodeId, Type, Options, SubsByDepth, items, Stanza, true),
case Removed of
[] ->
ok;
@@ -3116,7 +3116,6 @@ get_options_for_subs(NodeID, Subs) ->
end, [], Subs).
% TODO: merge broadcast code that way
-% TODO: pablo: Why is this commented? Seems to be present on trunk.
%broadcast(Host, Node, NodeId, Type, NodeOptions, Feature, Force, ElName, SubEls) ->
% case (get_option(NodeOptions, Feature) or Force) of
% true ->
@@ -3153,56 +3152,60 @@ broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTy
[LJID]
end,
%% Determine if the stanza should have SHIM ('SubID' and 'name') headers
- StanzaToSend = case SHIM of
- true ->
- Headers = lists:append(collection_shim(NodeName), subid_shim(SubIDs)),
- add_headers(Stanza, Headers);
- false ->
- Stanza
+ StanzaToSend = case {SHIM, SubIDs} of
+ {false, _} ->
+ Stanza;
+ {true, [_]} ->
+ add_shim_headers(Stanza, collection_shim(NodeName));
+ {true, SubIDs} ->
+ add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs)))
end,
- lists:foreach(fun({TU, TS, TR}) ->
- ejabberd_router:route(From, exmpp_jid:make(TU, TS, TR), StanzaToSend)
+ lists:foreach(fun(To) ->
+ ejabberd_router:route(From, exmpp_jid:make(To), StanzaToSend)
end, LJIDs)
- end, SubIDsByJID),
+ end, SubIDsByJID).
+
+broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) ->
+ broadcast_stanza({LUser, LServer, LResource}, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM),
+ SenderResource = case LResource of
+ undefined ->
+ case user_resources(LUser, LServer) of
+ [Resource|_] -> Resource;
+ _ -> <<"">>
+ end;
+ _ ->
+ LResource
+ end,
%% Handles implicit presence subscriptions
- case Host of
- {LUser, LServer, LResource} ->
- SenderResource = case LResource of
- undefined ->
- case user_resources(LUser, LServer) of
- [Resource|_] -> Resource;
- _ -> <<"">>
- end;
+ case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
+ C2SPid when is_pid(C2SPid) ->
+ Stanza = case get_option(NodeOptions, notification_type, headline) of
+ normal -> BaseStanza;
+ MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType))
+ end,
+ %% 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 = exmpp_jid:make(LUser, LServer),
+ ReplyTo = exmpp_jid:to_binary(exmpp_jid:make(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() ->
+ lists:foreach(fun(R) ->
+ ejabberd_router:route(Sender, exmpp_jid:make(U, S, R), StanzaToSend)
+ end, user_resources(U, S))
+ end)
+ end, Contacts);
_ ->
- LResource
- end,
- case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
- C2SPid when is_pid(C2SPid) ->
- %% 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 = exmpp_jid:make(LUser, LServer),
- %%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
- case catch ejabberd_c2s:get_subscribed(C2SPid) of
- Contacts when is_list(Contacts) ->
- lists:foreach(fun({U, S, _}) ->
- spawn(fun() ->
- lists:foreach(fun(R) ->
- ejabberd_router:route(Sender, exmpp_jid:make(U, S, R), Stanza)
- end, user_resources(U, S))
- end)
- end, Contacts);
- _ ->
- ok
- end,
- ok;
- _ ->
- ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, Stanza]),
ok
end;
_ ->
- ok
- end.
+ ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza])
+ end;
+broadcast_stanza(Host, _Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) ->
+ broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM).
subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
NodesToDeliver = fun(Depth, Node, Subs, Acc) ->
@@ -3811,9 +3814,16 @@ add_message_type(El, _Type) -> El.
%%
%% "[SHIM Headers] SHOULD be included after the event notification information
%% (i.e., as the last child of the stanza)".
-add_headers(#xmlel{} = El, HeaderEls) ->
- HeaderEl = #xmlel{ns = ?NS_SHIM, name = 'headers', children = HeaderEls},
- exmpp_xml:append_child(El, HeaderEl).
+
+add_shim_headers(Stanza, HeaderEls) ->
+ add_headers(Stanza, "headers", ?NS_SHIM, HeaderEls).
+
+add_extended_headers(Stanza, HeaderEls) ->
+ add_headers(Stanza, "addresses", ?NS_ADDRESS, HeaderEls).
+
+add_headers(#xmlel{children = Els} = Stanza, HeaderName, HeaderNS, HeaderEls) ->
+ HeaderEl = #xmlel{name = HeaderName, ns = HeaderNS, children = HeaderEls},
+ Stanza#xmlel{children = lists:append(Els, [HeaderEl])}.
%% Removed multiple elements
%% Didn't seem compliant, but not sure. Confirmation required.
@@ -3838,6 +3848,12 @@ subid_shim(SubIDs) ->
children = [?XMLCDATA(SubID)]}
|| SubID <- SubIDs].
+
+extended_headers(Jids) ->
+ [#xmlel{ns = ?NS_ADDRESS, name = 'address',
+ attrs = [?XMLATTR('type', <<"replyto">>), ?XMLATTR('jid', Jid)]}
+ || Jid <- Jids].
+
feature_check_packet(allow, _User, Server, Pres, {From, _To, El}, in) ->
Host = host(Server),
case exmpp_jid:prep_domain_as_list(From) of
diff --git a/src/mod_pubsub/mod_pubsub_odbc.erl b/src/mod_pubsub/mod_pubsub_odbc.erl
index 5a6c04328..7dd9becaa 100644
--- a/src/mod_pubsub/mod_pubsub_odbc.erl
+++ b/src/mod_pubsub/mod_pubsub_odbc.erl
@@ -2774,7 +2774,7 @@ event_stanza_withmoreels(Els, MoreEls) ->
%%%%%% broadcast functions
-broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, _From, Payload) ->
+broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, From, Payload) ->
%broadcast(Host, Node, NodeId, Options, none, true, 'items', ItemEls)
case get_collection_subscriptions(Host, Node) of
[] ->
@@ -2788,7 +2788,7 @@ broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, _From
Stanza = event_stanza(
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children =
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = itemAttr(ItemId), children = Content}]}]),
- broadcast_stanza(Host, Node, NodeId, Type, Options, SubsByDepth, items, Stanza, true),
+ broadcast_stanza(Host, From, Node, NodeId, Type, Options, SubsByDepth, items, Stanza, true),
case Removed of
[] ->
ok;
@@ -2964,56 +2964,60 @@ broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTy
[LJID]
end,
%% Determine if the stanza should have SHIM ('SubID' and 'name') headers
- StanzaToSend = case SHIM of
- true ->
- Headers = lists:append(collection_shim(NodeName), subid_shim(SubIDs)),
- add_headers(Stanza, Headers);
- false ->
- Stanza
+ StanzaToSend = case {SHIM, SubIDs} of
+ {false, _} ->
+ Stanza;
+ {true, [_]} ->
+ add_shim_headers(Stanza, collection_shim(NodeName));
+ {true, SubIDs} ->
+ add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs)))
end,
- lists:foreach(fun({TU, TS, TR}) ->
- ejabberd_router:route(From, exmpp_jid:make(TU, TS, TR), StanzaToSend)
+ lists:foreach(fun(To) ->
+ ejabberd_router:route(From, exmpp_jid:make(To), StanzaToSend)
end, LJIDs)
- end, SubIDsByJID),
+ end, SubIDsByJID).
+
+broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) ->
+ broadcast_stanza({LUser, LServer, LResource}, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM),
+ SenderResource = case LResource of
+ undefined ->
+ case user_resources(LUser, LServer) of
+ [Resource|_] -> Resource;
+ _ -> <<"">>
+ end;
+ _ ->
+ LResource
+ end,
%% Handles implicit presence subscriptions
- case Host of
- {LUser, LServer, LResource} ->
- SenderResource = case LResource of
- undefined ->
- case user_resources(LUser, LServer) of
- [Resource|_] -> Resource;
- _ -> <<"">>
- end;
+ case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
+ C2SPid when is_pid(C2SPid) ->
+ Stanza = case get_option(NodeOptions, notification_type, headline) of
+ normal -> BaseStanza;
+ MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType))
+ end,
+ %% 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 = exmpp_jid:make(LUser, LServer),
+ ReplyTo = exmpp_jid:to_binary(exmpp_jid:make(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() ->
+ lists:foreach(fun(R) ->
+ ejabberd_router:route(Sender, exmpp_jid:make(U, S, R), StanzaToSend)
+ end, user_resources(U, S))
+ end)
+ end, Contacts);
_ ->
- LResource
- end,
- case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
- C2SPid when is_pid(C2SPid) ->
- %% 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 = exmpp_jid:make(LUser, LServer),
- %%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
- case catch ejabberd_c2s:get_subscribed(C2SPid) of
- Contacts when is_list(Contacts) ->
- lists:foreach(fun({U, S, _}) ->
- spawn(fun() ->
- lists:foreach(fun(R) ->
- ejabberd_router:route(Sender, exmpp_jid:make(U, S, R), Stanza)
- end, user_resources(U, S))
- end)
- end, Contacts);
- _ ->
- ok
- end,
- ok;
- _ ->
- ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, Stanza]),
ok
end;
_ ->
- ok
- end.
+ ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza])
+ end;
+broadcast_stanza(Host, _Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) ->
+ broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM).
subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
NodesToDeliver = fun(Depth, Node, Subs, Acc) ->
@@ -3678,9 +3682,16 @@ add_message_type(El, _Type) -> El.
%%
%% "[SHIM Headers] SHOULD be included after the event notification information
%% (i.e., as the last child of the stanza)".
-add_headers(#xmlel{} = El, HeaderEls) ->
- HeaderEl = #xmlel{ns = ?NS_SHIM, name = 'headers', children = HeaderEls},
- exmpp_xml:append_child(El, HeaderEl).
+
+add_shim_headers(Stanza, HeaderEls) ->
+ add_headers(Stanza, "headers", ?NS_SHIM, HeaderEls).
+
+add_extended_headers(Stanza, HeaderEls) ->
+ add_headers(Stanza, "addresses", ?NS_ADDRESS, HeaderEls).
+
+add_headers(#xmlel{children = Els} = Stanza, HeaderName, HeaderNS, HeaderEls) ->
+ HeaderEl = #xmlel{name = HeaderName, ns = HeaderNS, children = HeaderEls},
+ Stanza#xmlel{children = lists:append(Els, [HeaderEl])}.
%% Removed multiple elements
%% Didn't seem compliant, but not sure. Confirmation required.
@@ -3705,6 +3716,12 @@ subid_shim(SubIDs) ->
children = [?XMLCDATA(SubID)]}
|| SubID <- SubIDs].
+
+extended_headers(Jids) ->
+ [#xmlel{ns = ?NS_ADDRESS, name = 'address',
+ attrs = [?XMLATTR('type', <<"replyto">>), ?XMLATTR('jid', Jid)]}
+ || Jid <- Jids].
+
feature_check_packet(allow, _User, Server, Pres, {From, _To, El}, in) ->
Host = host(Server),
case exmpp_jid:prep_domain_as_list(From) of
diff --git a/src/mod_pubsub/pubsub_odbc.patch b/src/mod_pubsub/pubsub_odbc.patch
index 6bfb4e35f..b7b5252ef 100644
--- a/src/mod_pubsub/pubsub_odbc.patch
+++ b/src/mod_pubsub/pubsub_odbc.patch
@@ -1,5 +1,5 @@
---- mod_pubsub.erl 2010-03-05 16:08:38.000000000 +0100
-+++ mod_pubsub_odbc.erl 2010-03-05 16:08:56.000000000 +0100
+--- mod_pubsub.erl 2010-03-05 18:31:50.000000000 +0100
++++ mod_pubsub_odbc.erl 2010-03-05 18:32:08.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.
@@ -707,16 +707,15 @@
_ -> Acc
end;
(_, Acc) ->
-@@ -3116,7 +2927,7 @@
+@@ -3116,6 +2927,7 @@
end, [], Subs).
% TODO: merge broadcast code that way
--% TODO: pablo: Why is this commented? Seems to be present on trunk.
+% TODO: pablo: why is this commented?
%broadcast(Host, Node, NodeId, Type, NodeOptions, Feature, Force, ElName, SubEls) ->
% case (get_option(NodeOptions, Feature) or Force) of
% true ->
-@@ -3315,6 +3126,30 @@
+@@ -3318,6 +3130,30 @@
Result
end.
@@ -747,7 +746,7 @@
%% @spec (Host, Options) -> MaxItems
%% Host = host()
%% Options = [Option]
-@@ -3713,7 +3548,13 @@
+@@ -3716,7 +3552,13 @@
tree_action(Host, Function, Args) ->
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
Fun = fun() -> tree_call(Host, Function, Args) end,
@@ -762,7 +761,7 @@
%% @doc
node plugin call.
node_call(Type, Function, Args) ->
-@@ -3733,13 +3574,13 @@
+@@ -3736,13 +3578,13 @@
node_action(Host, Type, Function, Args) ->
?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
@@ -778,7 +777,7 @@
case tree_call(Host, get_node, [Host, Node]) of
N when is_record(N, pubsub_node) ->
case Action(N) of
-@@ -3752,8 +3593,15 @@
+@@ -3755,8 +3597,15 @@
end
end, Trans).
@@ -796,7 +795,7 @@
{result, Result} -> {result, Result};
{error, Error} -> {error, Error};
{atomic, {result, Result}} -> {result, Result};
-@@ -3761,6 +3609,15 @@
+@@ -3764,6 +3613,15 @@
{aborted, Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
{error, 'internal-server-error'};
@@ -812,7 +811,7 @@
{'EXIT', Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
{error, 'internal-server-error'};
-@@ -3769,6 +3626,16 @@
+@@ -3772,6 +3630,16 @@
{error, 'internal-server-error'}
end.