diff options
author | Matthew Wild <mwild1@gmail.com> | 2020-09-17 13:04:46 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2020-09-17 13:04:46 +0100 |
commit | bd7d32aa8d11ae959b90ac18e922261d27d0a3a3 (patch) | |
tree | cdaad36e7fe037ca6bf26a2e1a2ca075d811fe74 | |
parent | 8a24ec9653c09224a5e2d011e61067ddb11c1fe0 (diff) | |
download | prosody-bd7d32aa8d11ae959b90ac18e922261d27d0a3a3.tar.gz prosody-bd7d32aa8d11ae959b90ac18e922261d27d0a3a3.zip |
mod_websocket: Switch partial frame buffering to util.dbuffer
This improves performance and enforces stanza size limits earlier
in the pipeline.
-rw-r--r-- | net/websocket/frames.lua | 4 | ||||
-rw-r--r-- | plugins/mod_websocket.lua | 11 |
2 files changed, 10 insertions, 5 deletions
diff --git a/net/websocket/frames.lua b/net/websocket/frames.lua index e1b5527a..65f9122c 100644 --- a/net/websocket/frames.lua +++ b/net/websocket/frames.lua @@ -20,8 +20,8 @@ local unpack = table.unpack or unpack; -- luacheck: ignore 113 local t_concat = table.concat; local s_char= string.char; -local s_pack = string.pack; -local s_unpack = string.unpack; +local s_pack = string.pack; -- luacheck: ignore 143 +local s_unpack = string.unpack; -- luacheck: ignore 143 if not s_pack and softreq"struct" then s_pack = softreq"struct".pack; diff --git a/plugins/mod_websocket.lua b/plugins/mod_websocket.lua index 177259e6..ad94486b 100644 --- a/plugins/mod_websocket.lua +++ b/plugins/mod_websocket.lua @@ -18,6 +18,7 @@ local contains_token = require "util.http".contains_token; local portmanager = require "core.portmanager"; local sm_destroy_session = require"core.sessionmanager".destroy_session; local log = module._log; +local dbuffer = require "util.dbuffer"; local websocket_frames = require"net.websocket.frames"; local parse_frame = websocket_frames.parse; @@ -27,6 +28,8 @@ local parse_close = websocket_frames.parse_close; local t_concat = table.concat; +local stanza_size_limit = module:get_option_number("c2s_stanza_size_limit", 10 * 1024 * 1024); +local frame_fragment_limit = module:get_option_number("websocket_frame_fragment_limit", 8); 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_set("cross_domain_websocket", {}); @@ -269,14 +272,16 @@ function handle_request(event) session.open_stream = session_open_stream; session.close = session_close; - local frameBuffer = ""; + -- max frame header is 22 bytes + local frameBuffer = dbuffer.new(stanza_size_limit + 22, frame_fragment_limit); add_filter(session, "bytes/in", function(data) + frameBuffer:write(data); + local cache = {}; - frameBuffer = frameBuffer .. data; local frame, length = parse_frame(frameBuffer); while frame do - frameBuffer = frameBuffer:sub(length + 1); + frameBuffer:discard(length); local result = handle_frame(frame); if not result then return; end cache[#cache+1] = filter_open_close(result); |