25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

add extended stanza addressing 'replyto' on PEP (EJAB-1198) (thanks karim)

This commit is contained in:
Christophe Romain 2010-03-05 18:33:12 +01:00
parent fe40651b0d
commit 7d497615a1
3 changed files with 139 additions and 107 deletions

View File

@ -2963,7 +2963,7 @@ event_stanza_withmoreels(Els, MoreEls) ->
%%%%%% broadcast functions %%%%%% 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) %broadcast(Host, Node, NodeId, Options, none, true, 'items', ItemEls)
case get_collection_subscriptions(Host, Node) of 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( Stanza = event_stanza(
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children = [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children =
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = itemAttr(ItemId), children = Content}]}]), [#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 case Removed of
[] -> [] ->
ok; ok;
@ -3116,7 +3116,6 @@ get_options_for_subs(NodeID, Subs) ->
end, [], Subs). end, [], Subs).
% TODO: merge broadcast code that way % 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) -> %broadcast(Host, Node, NodeId, Type, NodeOptions, Feature, Force, ElName, SubEls) ->
% case (get_option(NodeOptions, Feature) or Force) of % case (get_option(NodeOptions, Feature) or Force) of
% true -> % true ->
@ -3153,56 +3152,60 @@ broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTy
[LJID] [LJID]
end, end,
%% Determine if the stanza should have SHIM ('SubID' and 'name') headers %% Determine if the stanza should have SHIM ('SubID' and 'name') headers
StanzaToSend = case SHIM of StanzaToSend = case {SHIM, SubIDs} of
true -> {false, _} ->
Headers = lists:append(collection_shim(NodeName), subid_shim(SubIDs)), Stanza;
add_headers(Stanza, Headers); {true, [_]} ->
false -> add_shim_headers(Stanza, collection_shim(NodeName));
Stanza {true, SubIDs} ->
add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs)))
end, end,
lists:foreach(fun({TU, TS, TR}) -> lists:foreach(fun(To) ->
ejabberd_router:route(From, exmpp_jid:make(TU, TS, TR), StanzaToSend) ejabberd_router:route(From, exmpp_jid:make(To), StanzaToSend)
end, LJIDs) 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 %% Handles implicit presence subscriptions
case Host of case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
{LUser, LServer, LResource} -> C2SPid when is_pid(C2SPid) ->
SenderResource = case LResource of Stanza = case get_option(NodeOptions, notification_type, headline) of
undefined -> normal -> BaseStanza;
case user_resources(LUser, LServer) of MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType))
[Resource|_] -> Resource; end,
_ -> <<"">> %% set the from address on the notification to the bare JID of the account owner
end; %% 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 ok
end; end;
_ -> _ ->
ok ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza])
end. 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) -> subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
NodesToDeliver = fun(Depth, Node, Subs, Acc) -> 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 %% "[SHIM Headers] SHOULD be included after the event notification information
%% (i.e., as the last child of the <message/> stanza)". %% (i.e., as the last child of the <message/> stanza)".
add_headers(#xmlel{} = El, HeaderEls) ->
HeaderEl = #xmlel{ns = ?NS_SHIM, name = 'headers', children = HeaderEls}, add_shim_headers(Stanza, HeaderEls) ->
exmpp_xml:append_child(El, HeaderEl). 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 <header name=Collection>Foo</header/> elements %% Removed multiple <header name=Collection>Foo</header/> elements
%% Didn't seem compliant, but not sure. Confirmation required. %% Didn't seem compliant, but not sure. Confirmation required.
@ -3838,6 +3848,12 @@ subid_shim(SubIDs) ->
children = [?XMLCDATA(SubID)]} children = [?XMLCDATA(SubID)]}
|| SubID <- SubIDs]. || 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) -> feature_check_packet(allow, _User, Server, Pres, {From, _To, El}, in) ->
Host = host(Server), Host = host(Server),
case exmpp_jid:prep_domain_as_list(From) of case exmpp_jid:prep_domain_as_list(From) of

View File

@ -2774,7 +2774,7 @@ event_stanza_withmoreels(Els, MoreEls) ->
%%%%%% broadcast functions %%%%%% 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) %broadcast(Host, Node, NodeId, Options, none, true, 'items', ItemEls)
case get_collection_subscriptions(Host, Node) of 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( Stanza = event_stanza(
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children = [#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'items', attrs = nodeAttr(Node), children =
[#xmlel{ns = ?NS_PUBSUB_EVENT, name = 'item', attrs = itemAttr(ItemId), children = Content}]}]), [#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 case Removed of
[] -> [] ->
ok; ok;
@ -2964,56 +2964,60 @@ broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTy
[LJID] [LJID]
end, end,
%% Determine if the stanza should have SHIM ('SubID' and 'name') headers %% Determine if the stanza should have SHIM ('SubID' and 'name') headers
StanzaToSend = case SHIM of StanzaToSend = case {SHIM, SubIDs} of
true -> {false, _} ->
Headers = lists:append(collection_shim(NodeName), subid_shim(SubIDs)), Stanza;
add_headers(Stanza, Headers); {true, [_]} ->
false -> add_shim_headers(Stanza, collection_shim(NodeName));
Stanza {true, SubIDs} ->
add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs)))
end, end,
lists:foreach(fun({TU, TS, TR}) -> lists:foreach(fun(To) ->
ejabberd_router:route(From, exmpp_jid:make(TU, TS, TR), StanzaToSend) ejabberd_router:route(From, exmpp_jid:make(To), StanzaToSend)
end, LJIDs) 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 %% Handles implicit presence subscriptions
case Host of case ejabberd_sm:get_session_pid({LUser, LServer, SenderResource}) of
{LUser, LServer, LResource} -> C2SPid when is_pid(C2SPid) ->
SenderResource = case LResource of Stanza = case get_option(NodeOptions, notification_type, headline) of
undefined -> normal -> BaseStanza;
case user_resources(LUser, LServer) of MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType))
[Resource|_] -> Resource; end,
_ -> <<"">> %% set the from address on the notification to the bare JID of the account owner
end; %% 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 ok
end; end;
_ -> _ ->
ok ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza])
end. 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) -> subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
NodesToDeliver = fun(Depth, Node, Subs, Acc) -> 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 %% "[SHIM Headers] SHOULD be included after the event notification information
%% (i.e., as the last child of the <message/> stanza)". %% (i.e., as the last child of the <message/> stanza)".
add_headers(#xmlel{} = El, HeaderEls) ->
HeaderEl = #xmlel{ns = ?NS_SHIM, name = 'headers', children = HeaderEls}, add_shim_headers(Stanza, HeaderEls) ->
exmpp_xml:append_child(El, HeaderEl). 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 <header name=Collection>Foo</header/> elements %% Removed multiple <header name=Collection>Foo</header/> elements
%% Didn't seem compliant, but not sure. Confirmation required. %% Didn't seem compliant, but not sure. Confirmation required.
@ -3705,6 +3716,12 @@ subid_shim(SubIDs) ->
children = [?XMLCDATA(SubID)]} children = [?XMLCDATA(SubID)]}
|| SubID <- SubIDs]. || 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) -> feature_check_packet(allow, _User, Server, Pres, {From, _To, El}, in) ->
Host = host(Server), Host = host(Server),
case exmpp_jid:prep_domain_as_list(From) of case exmpp_jid:prep_domain_as_list(From) of

View File

@ -1,5 +1,5 @@
--- mod_pubsub.erl 2010-03-05 16:08:38.000000000 +0100 --- mod_pubsub.erl 2010-03-05 18:31:50.000000000 +0100
+++ mod_pubsub_odbc.erl 2010-03-05 16:08:56.000000000 +0100 +++ mod_pubsub_odbc.erl 2010-03-05 18:32:08.000000000 +0100
@@ -42,7 +42,7 @@ @@ -42,7 +42,7 @@
%%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see
%%% XEP-0060 section 12.18. %%% XEP-0060 section 12.18.
@ -707,16 +707,15 @@
_ -> Acc _ -> Acc
end; end;
(_, Acc) -> (_, Acc) ->
@@ -3116,7 +2927,7 @@ @@ -3116,6 +2927,7 @@
end, [], Subs). end, [], Subs).
% TODO: merge broadcast code that way % TODO: merge broadcast code that way
-% TODO: pablo: Why is this commented? Seems to be present on trunk.
+% TODO: pablo: why is this commented? +% TODO: pablo: why is this commented?
%broadcast(Host, Node, NodeId, Type, NodeOptions, Feature, Force, ElName, SubEls) -> %broadcast(Host, Node, NodeId, Type, NodeOptions, Feature, Force, ElName, SubEls) ->
% case (get_option(NodeOptions, Feature) or Force) of % case (get_option(NodeOptions, Feature) or Force) of
% true -> % true ->
@@ -3315,6 +3126,30 @@ @@ -3318,6 +3130,30 @@
Result Result
end. end.
@ -747,7 +746,7 @@
%% @spec (Host, Options) -> MaxItems %% @spec (Host, Options) -> MaxItems
%% Host = host() %% Host = host()
%% Options = [Option] %% Options = [Option]
@@ -3713,7 +3548,13 @@ @@ -3716,7 +3552,13 @@
tree_action(Host, Function, Args) -> tree_action(Host, Function, Args) ->
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
Fun = fun() -> tree_call(Host, Function, Args) end, Fun = fun() -> tree_call(Host, Function, Args) end,
@ -762,7 +761,7 @@
%% @doc <p>node plugin call.</p> %% @doc <p>node plugin call.</p>
node_call(Type, Function, Args) -> node_call(Type, Function, Args) ->
@@ -3733,13 +3574,13 @@ @@ -3736,13 +3578,13 @@
node_action(Host, Type, Function, Args) -> node_action(Host, Type, Function, Args) ->
?DEBUG("node_action ~p ~p ~p ~p",[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 case tree_call(Host, get_node, [Host, Node]) of
N when is_record(N, pubsub_node) -> N when is_record(N, pubsub_node) ->
case Action(N) of case Action(N) of
@@ -3752,8 +3593,15 @@ @@ -3755,8 +3597,15 @@
end end
end, Trans). end, Trans).
@ -796,7 +795,7 @@
{result, Result} -> {result, Result}; {result, Result} -> {result, Result};
{error, Error} -> {error, Error}; {error, Error} -> {error, Error};
{atomic, {result, Result}} -> {result, Result}; {atomic, {result, Result}} -> {result, Result};
@@ -3761,6 +3609,15 @@ @@ -3764,6 +3613,15 @@
{aborted, Reason} -> {aborted, Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
{error, 'internal-server-error'}; {error, 'internal-server-error'};
@ -812,7 +811,7 @@
{'EXIT', Reason} -> {'EXIT', Reason} ->
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
{error, 'internal-server-error'}; {error, 'internal-server-error'};
@@ -3769,6 +3626,16 @@ @@ -3772,6 +3630,16 @@
{error, 'internal-server-error'} {error, 'internal-server-error'}
end. end.