Diff

net/websocket/frames.lua @ 6905:0e81e3dab896

Merge 0.10->trunk
author Kim Alvefur <zash@zash.se>
date Sun, 11 Oct 2015 20:03:00 +0200
parent 6900:44a7e9152b9a
child 7259:d8300985f2bb
line wrap: on
line diff
--- a/net/websocket/frames.lua	Fri Oct 02 12:17:41 2015 +0200
+++ b/net/websocket/frames.lua	Sun Oct 11 20:03:00 2015 +0200
@@ -10,10 +10,8 @@
 local log = require "util.logger".init "websocket.frames";
 local random_bytes = require "util.random".bytes;
 
-local bit;
-pcall(function() bit = require"bit"; end);
-bit = bit or softreq"bit32"
-if not bit then log("error", "No bit module found. Either LuaJIT 2, lua-bitop or Lua 5.2 is required"); end
+local bit = assert(softreq"bit" or softreq"bit32",
+	"No bit module found. See https://prosody.im/doc/depends#bitop");
 local band = bit.band;
 local bor = bit.bor;
 local bxor = bit.bxor;
@@ -24,6 +22,13 @@
 local s_byte = string.byte;
 local s_char= string.char;
 local s_sub = string.sub;
+local s_pack = string.pack;
+local s_unpack = string.unpack;
+
+if not s_pack and softreq"struct" then
+	s_pack = softreq"struct".pack;
+	s_unpack = softreq"struct".unpack;
+end
 
 local function read_uint16be(str, pos)
 	local l1, l2 = s_byte(str, pos, pos+1);
@@ -32,8 +37,9 @@
 -- FIXME: this may lose precision
 local function read_uint64be(str, pos)
 	local l1, l2, l3, l4, l5, l6, l7, l8 = s_byte(str, pos, pos+7);
-	return lshift(l1, 56) + lshift(l2, 48) + lshift(l3, 40) + lshift(l4, 32)
-		+ lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8;
+	local h = lshift(l1, 24) + lshift(l2, 16) + lshift(l3, 8) + l4;
+	local l = lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8;
+	return h * 2^32 + l;
 end
 local function pack_uint16be(x)
 	return s_char(rshift(x, 8), band(x, 0xFF));
@@ -42,10 +48,29 @@
 	return band(rshift(x, n), 0xFF);
 end
 local function pack_uint64be(x)
-	return s_char(rshift(x, 56), get_byte(x, 48), get_byte(x, 40), get_byte(x, 32),
+	local h = band(x / 2^32, 2^32-1);
+	return s_char(get_byte(h, 24), get_byte(h, 16), get_byte(h, 8), band(h, 0xFF),
 		get_byte(x, 24), get_byte(x, 16), get_byte(x, 8), band(x, 0xFF));
 end
 
+if s_pack then
+	function pack_uint16be(x)
+		return s_pack(">I2", x);
+	end
+	function pack_uint64be(x)
+		return s_pack(">I8", x);
+	end
+end
+
+if s_unpack then
+	function read_uint16be(str, pos)
+		return s_unpack(">I2", str, pos);
+	end
+	function read_uint64be(str, pos)
+		return s_unpack(">I8", str, pos);
+	end
+end
+
 local function parse_frame_header(frame)
 	if #frame < 2 then return; end