comparison 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
comparison
equal deleted inserted replaced
689:4d21bd5dde49 690:5acc203972f3
48 tmp_byte = string.byte(frame, pos); 48 tmp_byte = string.byte(frame, pos);
49 result.FIN = band(tmp_byte, 0x80) > 0; 49 result.FIN = band(tmp_byte, 0x80) > 0;
50 result.RSV1 = band(tmp_byte, 0x40) > 0; 50 result.RSV1 = band(tmp_byte, 0x40) > 0;
51 result.RSV2 = band(tmp_byte, 0x20) > 0; 51 result.RSV2 = band(tmp_byte, 0x20) > 0;
52 result.RSV3 = band(tmp_byte, 0x10) > 0; 52 result.RSV3 = band(tmp_byte, 0x10) > 0;
53 result.opcode = band(tmp_byte, 0x0F) > 0; 53 result.opcode = band(tmp_byte, 0x0F);
54 54
55 pos = pos + 1; 55 pos = pos + 1;
56 tmp_byte = string.byte(frame, pos); 56 tmp_byte = string.byte(frame, pos);
57 result.MASK = band(tmp_byte, 0x80) > 0; 57 result.MASK = band(tmp_byte, 0x80) > 0;
58 result.length = band(tmp_byte, 0x7F); 58 result.length = band(tmp_byte, 0x7F);
255 session.notopen = true; 255 session.notopen = true;
256 session.stream:reset(); 256 session.stream:reset();
257 end 257 end
258 258
259 local filter = session.filter; 259 local filter = session.filter;
260 local buffer = "";
260 function session.data(data) 261 function session.data(data)
261 data = parse_frame(data).data; 262 local frame = parse_frame(data);
262 module:log("debug", "Websocket received: %s %i", data, #data) 263
263 -- COMPAT: Current client implementations send a self-closing <stream:stream> 264 module:log("debug", "Websocket received: %s (%i bytes)", frame.data, #frame.data);
264 data = data:gsub("/>$", ">"); 265 if frame.opcode == 0x00 or frame.opcode == 0x01 then -- Text or continuation frame
265 266 buffer = buffer .. frame.data;
266 data = filter("bytes/in", data); 267 else
267 if data then 268 log("warn", "Received frame with unsupported opcode %i", frame.opcode);
268 local ok, err = stream:feed(data); 269 return;
269 if ok then return; end 270 end
270 log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_")); 271
271 session:close("not-well-formed"); 272 if frame.FIN then
273 data = buffer;
274 buffer = "";
275
276 -- COMPAT: Current client implementations send a self-closing <stream:stream>
277 data = data:gsub("/>$", ">");
278
279 data = filter("bytes/in", data);
280 if data then
281 local ok, err = stream:feed(data);
282 if ok then return; end
283 log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_"));
284 session:close("not-well-formed");
285 end
272 end 286 end
273 end 287 end
274 288
275 function session.send(s) 289 function session.send(s)
276 conn:write(build_frame({ FIN = true, opcode = 0x01, data = tostring(s)})); 290 conn:write(build_frame({ FIN = true, opcode = 0x01, data = tostring(s)}));