diff mod_websocket/mod_websocket.lua @ 690:5acc203972f3

mod_websocket: Add fragmentation support
author Florian Zeitz <florob@babelmonkeys.de>
date Sun, 27 May 2012 19:05:07 +0200
parents 4d21bd5dde49
children 04662cc35280
line wrap: on
line diff
--- a/mod_websocket/mod_websocket.lua	Sun May 27 17:53:52 2012 +0200
+++ b/mod_websocket/mod_websocket.lua	Sun May 27 19:05:07 2012 +0200
@@ -50,7 +50,7 @@
 	result.RSV1 = band(tmp_byte, 0x40) > 0;
 	result.RSV2 = band(tmp_byte, 0x20) > 0;
 	result.RSV3 = band(tmp_byte, 0x10) > 0;
-	result.opcode = band(tmp_byte, 0x0F) > 0;
+	result.opcode = band(tmp_byte, 0x0F);
 
 	pos = pos + 1;
 	tmp_byte = string.byte(frame, pos);
@@ -257,18 +257,32 @@
 	end
 
 	local filter = session.filter;
+	local buffer = "";
 	function session.data(data)
-		data = parse_frame(data).data;
-		module:log("debug", "Websocket received: %s %i", data, #data)
-		-- COMPAT: Current client implementations send a self-closing <stream:stream>
-		data = data:gsub("/>$", ">");
+		local frame = parse_frame(data);
+
+		module:log("debug", "Websocket received: %s (%i bytes)", frame.data, #frame.data);
+		if frame.opcode == 0x00 or frame.opcode == 0x01 then -- Text or continuation frame
+			buffer = buffer .. frame.data;
+		else
+			log("warn", "Received frame with unsupported opcode %i", frame.opcode);
+			return;
+		end
 
-		data = filter("bytes/in", data);
-		if data then
-			local ok, err = stream:feed(data);
-			if ok then return; end
-			log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_"));
-			session:close("not-well-formed");
+		if frame.FIN then
+			data = buffer;
+			buffer = "";
+
+			-- COMPAT: Current client implementations send a self-closing <stream:stream>
+			data = data:gsub("/>$", ">");
+
+			data = filter("bytes/in", data);
+			if data then
+				local ok, err = stream:feed(data);
+				if ok then return; end
+				log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_"));
+				session:close("not-well-formed");
+			end
 		end
 	end