Comparison

plugins/mod_websocket.lua @ 11107:ddd0007e0f1b 0.11

mod_websocket: Switch partial frame buffering to util.dbuffer This improves performance and enforces stanza size limits earlier in the pipeline.
author Matthew Wild <mwild1@gmail.com>
date Thu, 17 Sep 2020 13:04:46 +0100
parent 10616:37936c72846d
child 11108:fa1821b56f75
comparison
equal deleted inserted replaced
11106:76f46c2579a2 11107:ddd0007e0f1b
16 local parse_xml = require "util.xml".parse; 16 local parse_xml = require "util.xml".parse;
17 local contains_token = require "util.http".contains_token; 17 local contains_token = require "util.http".contains_token;
18 local portmanager = require "core.portmanager"; 18 local portmanager = require "core.portmanager";
19 local sm_destroy_session = require"core.sessionmanager".destroy_session; 19 local sm_destroy_session = require"core.sessionmanager".destroy_session;
20 local log = module._log; 20 local log = module._log;
21 local dbuffer = require "util.dbuffer";
21 22
22 local websocket_frames = require"net.websocket.frames"; 23 local websocket_frames = require"net.websocket.frames";
23 local parse_frame = websocket_frames.parse; 24 local parse_frame = websocket_frames.parse;
24 local build_frame = websocket_frames.build; 25 local build_frame = websocket_frames.build;
25 local build_close = websocket_frames.build_close; 26 local build_close = websocket_frames.build_close;
26 local parse_close = websocket_frames.parse_close; 27 local parse_close = websocket_frames.parse_close;
27 28
28 local t_concat = table.concat; 29 local t_concat = table.concat;
29 30
31 local stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 10 * 1024 * 1024);
32 local frame_fragment_limit = module:get_option_number("websocket_frame_fragment_limit", 8);
30 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); 33 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
31 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure"); 34 local consider_websocket_secure = module:get_option_boolean("consider_websocket_secure");
32 local cross_domain = module:get_option_set("cross_domain_websocket", {}); 35 local cross_domain = module:get_option_set("cross_domain_websocket", {});
33 if cross_domain:contains("*") or cross_domain:contains(true) then 36 if cross_domain:contains("*") or cross_domain:contains(true) then
34 cross_domain = true; 37 cross_domain = true;
267 session.websocket_request = request; 270 session.websocket_request = request;
268 271
269 session.open_stream = session_open_stream; 272 session.open_stream = session_open_stream;
270 session.close = session_close; 273 session.close = session_close;
271 274
272 local frameBuffer = ""; 275 -- max frame header is 22 bytes
276 local frameBuffer = dbuffer.new(stanza_size_limit + 22, frame_fragment_limit);
273 add_filter(session, "bytes/in", function(data) 277 add_filter(session, "bytes/in", function(data)
278 frameBuffer:write(data);
279
274 local cache = {}; 280 local cache = {};
275 frameBuffer = frameBuffer .. data;
276 local frame, length = parse_frame(frameBuffer); 281 local frame, length = parse_frame(frameBuffer);
277 282
278 while frame do 283 while frame do
279 frameBuffer = frameBuffer:sub(length + 1); 284 frameBuffer:discard(length);
280 local result = handle_frame(frame); 285 local result = handle_frame(frame);
281 if not result then return; end 286 if not result then return; end
282 cache[#cache+1] = filter_open_close(result); 287 cache[#cache+1] = filter_open_close(result);
283 frame, length = parse_frame(frameBuffer); 288 frame, length = parse_frame(frameBuffer);
284 end 289 end