Diff

net/websocket/frames.lua @ 11164:4e5a2af9dd19 0.11

net.websocket.frames: Use C string XOR implementation
author Kim Alvefur <zash@zash.se>
date Wed, 14 Oct 2020 19:41:42 +0200
parent 11157:413bd21ba449
child 11166:51e5149ed0ad
line wrap: on
line diff
--- a/net/websocket/frames.lua	Sat Sep 07 13:37:47 2019 +0200
+++ b/net/websocket/frames.lua	Wed Oct 14 19:41:42 2020 +0200
@@ -13,12 +13,11 @@
 	"No bit module found. See https://prosody.im/doc/depends#bitop");
 local band = bit.band;
 local bor = bit.bor;
-local bxor = bit.bxor;
 local lshift = bit.lshift;
 local rshift = bit.rshift;
-local unpack = table.unpack or unpack; -- luacheck: ignore 113
+local sbit = require "util.strbitop";
+local sxor = sbit.sxor;
 
-local t_concat = table.concat;
 local s_char= string.char;
 local s_pack = string.pack; -- luacheck: ignore 143
 local s_unpack = string.unpack; -- luacheck: ignore 143
@@ -107,7 +106,7 @@
 	end
 
 	if result.MASK then
-		result.key = { frame:byte(length_bytes+3, length_bytes+6) };
+		result.key = frame:sub(length_bytes+3, length_bytes+6);
 	end
 
 	return result, header_length;
@@ -116,19 +115,7 @@
 -- XORs the string `str` with the array of bytes `key`
 -- TODO: optimize
 local function apply_mask(str, key, from, to)
-	from = from or 1
-	if from < 0 then from = #str + from + 1 end -- negative indices
-	to = to or #str
-	if to < 0 then to = #str + to + 1 end -- negative indices
-	local key_len = #key
-	local counter = 0;
-	local data = {};
-	for i = from, to do
-		local key_index = counter%key_len + 1;
-		counter = counter + 1;
-		data[counter] = s_char(bxor(key[key_index], str:byte(i)));
-	end
-	return t_concat(data);
+	return sxor(str:sub(from or 1, to or -1), key);
 end
 
 local function parse_frame_body(frame, header, pos)
@@ -175,15 +162,12 @@
 
 	local key = ""
 	if desc.MASK then
-		local key_a = desc.key
-		if key_a then
-			key = s_char(unpack(key_a, 1, 4));
-		else
+		key = desc.key
+		if not key then
 			key = random_bytes(4);
-			key_a = {key:byte(1,4)};
 		end
 		b2 = bor(b2, 0x80);
-		data = apply_mask(data, key_a);
+		data = apply_mask(data, key);
 	end
 
 	return s_char(b1, b2) .. length_extra .. key .. data