Comparison

net/websocket/frames.lua @ 11106:76f46c2579a2 0.11

net.websocket.frames: Allow all methods to work on non-string objects Instead of using the string library, use methods from the passed object, which are assumed to be equivalent. This provides compatibility with objects from util.ringbuffer and util.dbuffer, for example.
author Matthew Wild <mwild1@gmail.com>
date Thu, 17 Sep 2020 13:00:19 +0100
parent 8728:41c959c5c84b
child 11107:ddd0007e0f1b
comparison
equal deleted inserted replaced
11105:3c0940f3cf74 11106:76f46c2579a2
14 local band = bit.band; 14 local band = bit.band;
15 local bor = bit.bor; 15 local bor = bit.bor;
16 local bxor = bit.bxor; 16 local bxor = bit.bxor;
17 local lshift = bit.lshift; 17 local lshift = bit.lshift;
18 local rshift = bit.rshift; 18 local rshift = bit.rshift;
19 local unpack = table.unpack or unpack; -- luacheck: ignore 113
19 20
20 local t_concat = table.concat; 21 local t_concat = table.concat;
21 local s_byte = string.byte;
22 local s_char= string.char; 22 local s_char= string.char;
23 local s_sub = string.sub; 23 local s_pack = string.pack;
24 local s_pack = string.pack; -- luacheck: ignore 143 24 local s_unpack = string.unpack;
25 local s_unpack = string.unpack; -- luacheck: ignore 143
26 25
27 if not s_pack and softreq"struct" then 26 if not s_pack and softreq"struct" then
28 s_pack = softreq"struct".pack; 27 s_pack = softreq"struct".pack;
29 s_unpack = softreq"struct".unpack; 28 s_unpack = softreq"struct".unpack;
30 end 29 end
31 30
32 local function read_uint16be(str, pos) 31 local function read_uint16be(str, pos)
33 local l1, l2 = s_byte(str, pos, pos+1); 32 local l1, l2 = str:byte(pos, pos+1);
34 return l1*256 + l2; 33 return l1*256 + l2;
35 end 34 end
36 -- FIXME: this may lose precision 35 -- FIXME: this may lose precision
37 local function read_uint64be(str, pos) 36 local function read_uint64be(str, pos)
38 local l1, l2, l3, l4, l5, l6, l7, l8 = s_byte(str, pos, pos+7); 37 local l1, l2, l3, l4, l5, l6, l7, l8 = str:byte(pos, pos+7);
39 local h = lshift(l1, 24) + lshift(l2, 16) + lshift(l3, 8) + l4; 38 local h = lshift(l1, 24) + lshift(l2, 16) + lshift(l3, 8) + l4;
40 local l = lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8; 39 local l = lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8;
41 return h * 2^32 + l; 40 return h * 2^32 + l;
42 end 41 end
43 local function pack_uint16be(x) 42 local function pack_uint16be(x)
61 end 60 end
62 end 61 end
63 62
64 if s_unpack then 63 if s_unpack then
65 function read_uint16be(str, pos) 64 function read_uint16be(str, pos)
65 if type(str) ~= "string" then
66 str, pos = str:sub(pos, pos+1), 1;
67 end
66 return s_unpack(">I2", str, pos); 68 return s_unpack(">I2", str, pos);
67 end 69 end
68 function read_uint64be(str, pos) 70 function read_uint64be(str, pos)
71 if type(str) ~= "string" then
72 str, pos = str:sub(pos, pos+7), 1;
73 end
69 return s_unpack(">I8", str, pos); 74 return s_unpack(">I8", str, pos);
70 end 75 end
71 end 76 end
72 77
73 local function parse_frame_header(frame) 78 local function parse_frame_header(frame)
74 if #frame < 2 then return; end 79 if #frame < 2 then return; end
75 80
76 local byte1, byte2 = s_byte(frame, 1, 2); 81 local byte1, byte2 = frame:byte(1, 2);
77 local result = { 82 local result = {
78 FIN = band(byte1, 0x80) > 0; 83 FIN = band(byte1, 0x80) > 0;
79 RSV1 = band(byte1, 0x40) > 0; 84 RSV1 = band(byte1, 0x40) > 0;
80 RSV2 = band(byte1, 0x20) > 0; 85 RSV2 = band(byte1, 0x20) > 0;
81 RSV3 = band(byte1, 0x10) > 0; 86 RSV3 = band(byte1, 0x10) > 0;
100 elseif length_bytes == 8 then 105 elseif length_bytes == 8 then
101 result.length = read_uint64be(frame, 3); 106 result.length = read_uint64be(frame, 3);
102 end 107 end
103 108
104 if result.MASK then 109 if result.MASK then
105 result.key = { s_byte(frame, length_bytes+3, length_bytes+6) }; 110 result.key = { frame:byte(length_bytes+3, length_bytes+6) };
106 end 111 end
107 112
108 return result, header_length; 113 return result, header_length;
109 end 114 end
110 115
119 local counter = 0; 124 local counter = 0;
120 local data = {}; 125 local data = {};
121 for i = from, to do 126 for i = from, to do
122 local key_index = counter%key_len + 1; 127 local key_index = counter%key_len + 1;
123 counter = counter + 1; 128 counter = counter + 1;
124 data[counter] = s_char(bxor(key[key_index], s_byte(str, i))); 129 data[counter] = s_char(bxor(key[key_index], str:byte(i)));
125 end 130 end
126 return t_concat(data); 131 return t_concat(data);
127 end 132 end
128 133
129 local function parse_frame_body(frame, header, pos) 134 local function parse_frame_body(frame, header, pos)
187 local function parse_close(data) 192 local function parse_close(data)
188 local code, message 193 local code, message
189 if #data >= 2 then 194 if #data >= 2 then
190 code = read_uint16be(data, 1); 195 code = read_uint16be(data, 1);
191 if #data > 2 then 196 if #data > 2 then
192 message = s_sub(data, 3); 197 message = data:sub(3);
193 end 198 end
194 end 199 end
195 return code, message 200 return code, message
196 end 201 end
197 202