Software /
code /
prosody
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 |