1 |
|
%% @doc This module builds an interface to c2s event handling |
2 |
|
-module(mongoose_c2s_hooks). |
3 |
|
|
4 |
|
-type fn() :: fun((mongoose_acc:t(), params(), gen_hook:extra()) -> result()). |
5 |
|
-type params() :: #{c2s_data := mongoose_c2s:data(), |
6 |
|
c2s_state := mongoose_c2s:state(), |
7 |
|
event_type := undefined | gen_statem:event_type(), |
8 |
|
event_tag => atom(), |
9 |
|
event_content := undefined | term(), |
10 |
|
reason := undefined | term()}. |
11 |
|
-type result() :: gen_hook:hook_fn_ret(mongoose_acc:t()). |
12 |
|
-export_type([fn/0, params/0, result/0]). |
13 |
|
|
14 |
|
%% XML handlers |
15 |
|
-export([user_send_packet/3, |
16 |
|
user_receive_packet/3, |
17 |
|
user_send_message/3, |
18 |
|
user_send_iq/3, |
19 |
|
user_send_presence/3, |
20 |
|
user_send_xmlel/3, |
21 |
|
user_receive_message/3, |
22 |
|
user_receive_iq/3, |
23 |
|
user_receive_presence/3, |
24 |
|
user_receive_xmlel/3, |
25 |
|
xmpp_presend_element/3 |
26 |
|
]). |
27 |
|
|
28 |
|
%% General event handlers |
29 |
|
-export([foreign_event/3, |
30 |
|
user_open_session/3, |
31 |
|
user_terminate/3, |
32 |
|
reroute_unacked_messages/3, |
33 |
|
user_stop_request/3, |
34 |
|
user_socket_closed/3, |
35 |
|
user_socket_error/3]). |
36 |
|
|
37 |
|
%%% @doc Event triggered after a user sends _any_ packet to the server. |
38 |
|
%%% Examples of handlers can be metrics, archives, and any other subsystem |
39 |
|
%%% that wants to see all stanzas the user delivers. |
40 |
|
-spec user_send_packet(HostType, Acc, Params) -> Result when |
41 |
|
HostType :: mongooseim:host_type(), |
42 |
|
Acc :: mongoose_acc:t(), |
43 |
|
Params :: params(), |
44 |
|
Result :: result(). |
45 |
|
user_send_packet(HostType, Acc, Params) -> |
46 |
13320 |
gen_hook:run_fold(user_send_packet, HostType, Acc, Params). |
47 |
|
|
48 |
|
%% @doc Triggered when a user receives a packet through any routing mechanism. |
49 |
|
%% Examples of handlers can be metrics or carbons. |
50 |
|
-spec user_receive_packet(HostType, Acc, Params) -> Result when |
51 |
|
HostType :: mongooseim:host_type(), |
52 |
|
Acc :: mongoose_acc:t(), |
53 |
|
Params :: params(), |
54 |
|
Result :: result(). |
55 |
|
user_receive_packet(HostType, Acc, Params) -> |
56 |
19812 |
gen_hook:run_fold(user_receive_packet, HostType, Acc, Params). |
57 |
|
|
58 |
|
%% @doc Triggered when the user sends a stanza of type `message' |
59 |
|
-spec user_send_message(HostType, Acc, Params) -> Result when |
60 |
|
HostType :: mongooseim:host_type(), |
61 |
|
Acc :: mongoose_acc:t(), |
62 |
|
Params :: params(), |
63 |
|
Result :: result(). |
64 |
|
user_send_message(HostType, Acc, Params) -> |
65 |
1685 |
gen_hook:run_fold(user_send_message, HostType, Acc, Params). |
66 |
|
|
67 |
|
%% @doc Triggered when the user sends a stanza of type `iq' |
68 |
|
-spec user_send_iq(HostType, Acc, Params) -> Result when |
69 |
|
HostType :: mongooseim:host_type(), |
70 |
|
Acc :: mongoose_acc:t(), |
71 |
|
Params :: params(), |
72 |
|
Result :: result(). |
73 |
|
user_send_iq(HostType, Acc, Params) -> |
74 |
6045 |
Acc1 = mongoose_iq:update_acc_info(Acc), |
75 |
6045 |
gen_hook:run_fold(user_send_iq, HostType, Acc1, Params). |
76 |
|
|
77 |
|
%% @doc Triggered when the user sends a stanza of type `presence' |
78 |
|
-spec user_send_presence(HostType, Acc, Params) -> Result when |
79 |
|
HostType :: mongooseim:host_type(), |
80 |
|
Acc :: mongoose_acc:t(), |
81 |
|
Params :: params(), |
82 |
|
Result :: result(). |
83 |
|
user_send_presence(HostType, Acc, Params) -> |
84 |
4422 |
gen_hook:run_fold(user_send_presence, HostType, Acc, Params). |
85 |
|
|
86 |
|
%% @doc Triggered when the user sends a packet which is not a proper XMPP stanza, i.e., |
87 |
|
%% it is not of types `message', `iq', nor `presence'. |
88 |
|
-spec user_send_xmlel(HostType, Acc, Params) -> Result when |
89 |
|
HostType :: mongooseim:host_type(), |
90 |
|
Acc :: mongoose_acc:t(), |
91 |
|
Params :: params(), |
92 |
|
Result :: result(). |
93 |
|
user_send_xmlel(HostType, Acc, Params) -> |
94 |
2307 |
gen_hook:run_fold(user_send_xmlel, HostType, Acc, Params). |
95 |
|
|
96 |
|
|
97 |
|
%% @doc Triggered when the user received a stanza of type `message' |
98 |
|
-spec user_receive_message(HostType, Acc, Params) -> Result when |
99 |
|
HostType :: mongooseim:host_type(), |
100 |
|
Acc :: mongoose_acc:t(), |
101 |
|
Params :: params(), |
102 |
|
Result :: result(). |
103 |
|
user_receive_message(HostType, Acc, Params) -> |
104 |
2460 |
gen_hook:run_fold(user_receive_message, HostType, Acc, Params). |
105 |
|
|
106 |
|
%% @doc Triggered when the user received a stanza of type `iq' |
107 |
|
-spec user_receive_iq(HostType, Acc, Params) -> Result when |
108 |
|
HostType :: mongooseim:host_type(), |
109 |
|
Acc :: mongoose_acc:t(), |
110 |
|
Params :: params(), |
111 |
|
Result :: result(). |
112 |
|
user_receive_iq(HostType, Acc, Params) -> |
113 |
7825 |
Acc1 = mongoose_iq:update_acc_info(Acc), |
114 |
7825 |
gen_hook:run_fold(user_receive_iq, HostType, Acc1, Params). |
115 |
|
|
116 |
|
%% @doc Triggered when the user received a stanza of type `presence' |
117 |
|
-spec user_receive_presence(HostType, Acc, Params) -> Result when |
118 |
|
HostType :: mongooseim:host_type(), |
119 |
|
Acc :: mongoose_acc:t(), |
120 |
|
Params :: params(), |
121 |
|
Result :: result(). |
122 |
|
user_receive_presence(HostType, Acc, Params) -> |
123 |
9525 |
gen_hook:run_fold(user_receive_presence, HostType, Acc, Params). |
124 |
|
|
125 |
|
%% @doc Triggered when the user received a packet which is not a proper XMPP stanza, i.e., |
126 |
|
%% it is not of types `message', `iq', nor `presence'. |
127 |
|
-spec user_receive_xmlel(HostType, Acc, Params) -> Result when |
128 |
|
HostType :: mongooseim:host_type(), |
129 |
|
Acc :: mongoose_acc:t(), |
130 |
|
Params :: params(), |
131 |
|
Result :: result(). |
132 |
|
user_receive_xmlel(HostType, Acc, Params) -> |
133 |
1 |
gen_hook:run_fold(user_receive_xmlel, HostType, Acc, Params). |
134 |
|
|
135 |
|
-spec xmpp_presend_element(HostType, Acc, Params) -> Result when |
136 |
|
HostType :: mongooseim:host_type(), |
137 |
|
Acc :: mongoose_acc:t(), |
138 |
|
Params :: params(), |
139 |
|
Result :: result(). |
140 |
|
xmpp_presend_element(HostType, Acc, Params) -> |
141 |
15892 |
gen_hook:run_fold(xmpp_presend_element, HostType, Acc, Params). |
142 |
|
|
143 |
|
%% @doc Triggered when the c2s statem process receives any event it is not defined to handle. |
144 |
|
%% These events should not by default stop the process, and they are expected to |
145 |
|
%% be handled by a single event handler, which should then stop the hook fold. |
146 |
|
%% If no handler handles the event, it is logged. |
147 |
|
-spec foreign_event(HostType, Acc, Params) -> Result when |
148 |
|
HostType :: mongooseim:host_type(), |
149 |
|
Acc :: mongoose_acc:t(), |
150 |
|
Params :: map(), |
151 |
|
Result :: result(). |
152 |
|
foreign_event(HostType, Acc, Params) -> |
153 |
924 |
gen_hook:run_fold(foreign_event, HostType, Acc, Params). |
154 |
|
|
155 |
|
%% @doc Triggered when the user binds a resource and attempts to open a session |
156 |
|
%% This is ran _before_ registering the user in the session table. |
157 |
|
%% If any handler returns a `stop' tag, the session establishment is rejected |
158 |
|
%% and the user may be allowed to retry |
159 |
|
-spec user_open_session(HostType, Acc, Params) -> Result when |
160 |
|
HostType :: mongooseim:host_type(), |
161 |
|
Acc :: mongoose_acc:t(), |
162 |
|
Params :: params(), |
163 |
|
Result :: result(). |
164 |
|
user_open_session(HostType, Acc, Params) -> |
165 |
3966 |
gen_hook:run_fold(user_open_session, HostType, Acc, Params). |
166 |
|
|
167 |
|
%% @doc Triggered when the user session is irrevocably terminating. |
168 |
|
%% This is ran _before_ removing the user from the session table and closing his socket. |
169 |
|
-spec user_terminate(HostType, Acc, Params) -> Result when |
170 |
|
HostType :: mongooseim:host_type(), |
171 |
|
Acc :: mongoose_acc:t(), |
172 |
|
Params :: params(), |
173 |
|
Result :: mongoose_acc:t(). |
174 |
|
user_terminate(HostType, Acc, Params) -> |
175 |
5137 |
{_, Res} = gen_hook:run_fold(user_terminate, HostType, Acc, Params), |
176 |
5137 |
Res. |
177 |
|
|
178 |
|
%% @doc Triggered when the user session is irrevocably terminating. |
179 |
|
%% This is ran _after_ removing the user from the session table, but before closing the socket |
180 |
|
-spec reroute_unacked_messages(HostType, Acc, Params) -> Result when |
181 |
|
HostType :: mongooseim:host_type(), |
182 |
|
Acc :: mongoose_acc:t(), |
183 |
|
Params :: params(), |
184 |
|
Result :: mongoose_acc:t(). |
185 |
|
reroute_unacked_messages(HostType, Acc, Params) -> |
186 |
5137 |
{_, Res} = gen_hook:run_fold(reroute_unacked_messages, HostType, Acc, Params), |
187 |
5137 |
Res. |
188 |
|
|
189 |
|
%% These conditions required that one and only one handler declared full control over it, |
190 |
|
%% by making the hook stop at that point. If so, the process remains alive, |
191 |
|
%% in control of the handler, otherwise, the condition is treated as terminal. |
192 |
|
%% See `mongoose_c2s:stop_if_unhandled/3' |
193 |
|
|
194 |
|
%% @doc Triggered when an external event requests the connection to be closed. |
195 |
|
-spec user_stop_request(HostType, Acc, Params) -> Result when |
196 |
|
HostType :: mongooseim:host_type(), |
197 |
|
Acc :: mongoose_acc:t(), |
198 |
|
Params :: params(), |
199 |
|
Result :: result(). |
200 |
|
user_stop_request(HostType, Acc, Params) -> |
201 |
728 |
gen_hook:run_fold(user_stop_request, HostType, Acc, Params). |
202 |
|
|
203 |
|
%% @doc Triggered when the socket dies. |
204 |
|
-spec user_socket_closed(HostType, Acc, Params) -> Result when |
205 |
|
HostType :: mongooseim:host_type(), |
206 |
|
Acc :: mongoose_acc:t(), |
207 |
|
Params :: params(), |
208 |
|
Result :: result(). |
209 |
|
user_socket_closed(HostType, Acc, Params) -> |
210 |
583 |
gen_hook:run_fold(user_socket_closed, HostType, Acc, Params). |
211 |
|
|
212 |
|
%% @doc Triggered when the socket errors out. |
213 |
|
-spec user_socket_error(HostType, Acc, Params) -> Result when |
214 |
|
HostType :: mongooseim:host_type(), |
215 |
|
Acc :: mongoose_acc:t(), |
216 |
|
Params :: params(), |
217 |
|
Result :: result(). |
218 |
|
user_socket_error(HostType, Acc, Params) -> |
219 |
:-( |
gen_hook:run_fold(user_socket_error, HostType, Acc, Params). |