Merge 0.10->trunk
[prosody.git] / plugins / mod_websocket.lua
index d32529802e810c1009b1cf7e8e1062c5948c6c98..a3f5318c9b54636f8caec1b747bf39fd56bd9033 100644 (file)
@@ -4,9 +4,11 @@
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
+-- luacheck: ignore 431/log
 
 module:set_global();
 
+local add_task = require "util.timer".add_task;
 local add_filter = require "util.filters".add_filter;
 local sha1 = require "util.hashes".sha1;
 local base64 = require "util.encodings".base64.encode;
@@ -24,6 +26,7 @@ local parse_close = websocket_frames.parse_close;
 
 local t_concat = table.concat;
 
+local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure");
 local cross_domain = module:get_option("cross_domain_websocket");
 if cross_domain then
@@ -128,7 +131,7 @@ local function filter_open_close(data)
 
        return data;
 end
-function handle_request(event, path)
+function handle_request(event)
        local request, response = event.request, event.response;
        local conn = response.conn;
 
@@ -223,8 +226,7 @@ function handle_request(event, path)
                        frame.opcode = 0xA;
                        conn:write(build_frame(frame));
                        return "";
-               elseif opcode == 0xA then -- Pong frame
-                       module:log("warn", "Received unexpected pong frame: " .. tostring(frame.data));
+               elseif opcode == 0xA then -- Pong frame, MAY be sent unsolicited, eg as keepalive
                        return "";
                else
                        log("warn", "Received frame with unsupported opcode %i", opcode);
@@ -272,7 +274,7 @@ function handle_request(event, path)
                        attr["xmlns:stream"] = attr["xmlns:stream"] or xmlns_streams;
                end
                return stanza;
-       end);
+       end, -1000);
 
        add_filter(session, "bytes/out", function(data)
                return build_frame({ FIN = true, opcode = 0x01, data = tostring(data)});
@@ -288,6 +290,15 @@ function handle_request(event, path)
        return "";
 end
 
+local function keepalive(event)
+       local session = event.session;
+       if session.open_stream == session_open_stream then
+               return session.conn:write(build_frame({ opcode = 0x9, }));
+       end
+end
+
+module:hook("c2s-read-timeout", keepalive, -0.9);
+
 function module.add_host(module)
        module:depends("http");
        module:provides("http", {
@@ -298,4 +309,5 @@ function module.add_host(module)
                        ["GET /"] = handle_request;
                };
        });
+       module:hook("c2s-read-timeout", keepalive, -0.9);
 end