1 |
|
-module(mongoose_client_api_sse). |
2 |
|
-behaviour(lasse_handler). |
3 |
|
|
4 |
|
-include("mongoose.hrl"). |
5 |
|
-include("jlib.hrl"). |
6 |
|
|
7 |
|
-export([init/3]). |
8 |
|
-export([handle_notify/2]). |
9 |
|
-export([handle_info/2]). |
10 |
|
-export([handle_error/3]). |
11 |
|
-export([terminate/3]). |
12 |
|
|
13 |
|
init(_InitArgs, _LastEvtId, Req) -> |
14 |
3 |
?LOG_DEBUG(#{what => client_api_sse_init, req => Req}), |
15 |
3 |
{cowboy_rest, Req1, State0} = mongoose_client_api:init(Req, []), |
16 |
3 |
{Authorization, Req2, State} = mongoose_client_api:is_authorized(Req1, State0), |
17 |
3 |
maybe_init(Authorization, Req2, State#{id => 1}). |
18 |
|
|
19 |
|
maybe_init(true, Req, #{jid := JID, creds := Creds} = State) -> |
20 |
3 |
SID = ejabberd_sm:make_new_sid(), |
21 |
3 |
UUID = uuid:uuid_to_string(uuid:get_v4(), binary_standard), |
22 |
3 |
Resource = <<"sse-", UUID/binary>>, |
23 |
3 |
NewJid = jid:replace_resource(JID, Resource), |
24 |
3 |
HostType = mongoose_credentials:host_type(Creds), |
25 |
3 |
ejabberd_sm:open_session(HostType, SID, NewJid, 1, #{}), |
26 |
3 |
{ok, Req, State#{sid => SID, jid => NewJid}}; |
27 |
|
maybe_init(true, Req, State) -> |
28 |
|
%% This is for OPTIONS method |
29 |
:-( |
{shutdown, 200, #{}, <<>>, Req, State}; |
30 |
|
maybe_init({false, Value}, Req, State) -> |
31 |
:-( |
Headers = #{<<"www-authenticate">> => Value}, |
32 |
:-( |
{shutdown, 401, Headers, <<>>, Req, State}. |
33 |
|
|
34 |
|
handle_notify(Msg, State) -> |
35 |
:-( |
?UNEXPECTED_INFO(Msg), |
36 |
:-( |
{nosend, State}. |
37 |
|
|
38 |
|
handle_info({route, _From, _To, Acc}, State) -> |
39 |
3 |
#xmlel{ name = TagName } = El = mongoose_acc:element(Acc), |
40 |
3 |
handle_msg(TagName, Acc, El, State); |
41 |
|
handle_info(Msg, State) -> |
42 |
:-( |
?UNEXPECTED_INFO(Msg), |
43 |
:-( |
{nosend, State}. |
44 |
|
|
45 |
|
handle_msg(<<"message">>, Acc, El, State) -> |
46 |
3 |
Timestamp = os:system_time(microsecond), |
47 |
3 |
Type = mongoose_acc:stanza_type(Acc), |
48 |
3 |
maybe_send_message_event(Type, El, Timestamp, State). |
49 |
|
|
50 |
|
handle_error(Msg, Reason, State) -> |
51 |
:-( |
?LOG_WARNING(#{what => sse_handle_error, msg => Msg, reason => Reason}), |
52 |
:-( |
{nosend, State}. |
53 |
|
|
54 |
|
terminate(_Reason, _Req, #{creds := Creds} = State) -> |
55 |
:-( |
case maps:get(sid, State, undefined) of |
56 |
|
undefined -> |
57 |
:-( |
ok; |
58 |
|
SID -> |
59 |
:-( |
JID = #jid{server = S} = maps:get(jid, State), |
60 |
:-( |
Acc = mongoose_acc:new( |
61 |
|
#{location => ?LOCATION, |
62 |
|
lserver => S, |
63 |
|
host_type => mongoose_credentials:host_type(Creds), |
64 |
|
element => undefined}), |
65 |
:-( |
ejabberd_sm:close_session(Acc, SID, JID, normal) |
66 |
|
end, |
67 |
:-( |
State. |
68 |
|
|
69 |
|
maybe_send_message_event(<<"chat">>, Packet, Timestamp, #{id := ID} = State) -> |
70 |
1 |
Data = jiffy:encode(mongoose_client_api_messages:encode(Packet, Timestamp)), |
71 |
1 |
Event = #{id => integer_to_binary(ID), event => <<"message">>, data => Data}, |
72 |
1 |
{send, Event, State#{id := ID + 1}}; |
73 |
|
maybe_send_message_event(<<"groupchat">>, Packet, Timestamp, #{id := ID} = State) -> |
74 |
2 |
Data = jiffy:encode(mongoose_client_api_rooms_messages:encode(Packet, Timestamp)), |
75 |
2 |
Event = #{id => integer_to_binary(ID), event => <<"room.message">>, data => Data}, |
76 |
2 |
{send, Event, State#{id := ID + 1}}; |
77 |
|
maybe_send_message_event(_, _, _, State) -> |
78 |
:-( |
{nosend, State}. |