mod_muc_webchat_url: Fix default url
[prosody-modules.git] / mod_muc_eventsource / mod_muc_eventsource.lua
blobd9ba370f048859c37e93db5ef8816d2e69328fd5
1 module:depends("http");
2 local nodeprep = require "util.encodings".stringprep.nodeprep;
4 local jid_split = require "util.jid".split;
5 local json = require "util.json";
7 local streams = {};
9 function client_closed(response)
10 local node = response._eventsource_node;
11 module:log("debug", "Destroying client for %q", node);
12 streams[node][response] = nil;
13 if next(streams[node]) == nil then
14 streams[node] = nil;
15 end
16 end
18 function serve_stream(event, node)
19 local response = event.response;
21 node = nodeprep(node);
22 if node == nil then
23 return 400;
24 end
26 module:log("debug", "Client subscribed to: %s", node);
28 response.on_destroy = client_closed;
29 response._eventsource_node = node;
31 response.conn:write(table.concat({
32 "HTTP/1.1 200 OK";
33 "Content-Type: text/event-stream";
34 "Access-Control-Allow-Origin: *";
35 "Access-Control-Allow-Methods: GET";
36 "Access-Control-Max-Age: 7200";
37 "";
38 "";
39 }, "\r\n"));
41 local clientlist = streams[node];
42 if not clientlist then
43 clientlist = {};
44 streams[node] = clientlist;
45 end
46 clientlist[response] = response.conn;
48 return true;
49 end
51 function handle_message(event)
52 local room, stanza = event.room, event.stanza;
53 local node = (jid_split(event.room.jid));
54 local clientlist = streams[node];
55 if not clientlist then module:log("debug", "No clients for %q", node); return; end
57 -- Extract body from message
58 local body = event.stanza:get_child_text("body");
59 if not body then
60 return;
61 end
62 local nick = select(3, jid_split(stanza.attr.from));
63 -- Encode body and broadcast to eventsource subscribers
64 local json_data = json.encode({
65 nick = nick;
66 body = body;
67 });
68 local data = "data: "..json_data:gsub("\n", "\ndata: \n").."\n\n";
69 for response, conn in pairs(clientlist) do
70 conn:write(data);
71 end
72 end
74 module:provides("http", {
75 name = "eventsource";
76 route = {
77 ["GET /*"] = serve_stream;
79 });
82 module:hook("muc-broadcast-message", handle_message);