Mercurial > prosody-hg
comparison net/websocket/frames.lua @ 11114:6a608ecb3471
Merge 0.11->trunk
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 29 Sep 2020 15:30:48 +0100 |
| parents | 48f7cda4174d bcc701377fe4 |
| children | 3a72cb126d6c |
comparison
equal
deleted
inserted
replaced
| 11102:5a0ff475ecfd | 11114:6a608ecb3471 |
|---|---|
| 16 local lshift = bit.lshift; | 16 local lshift = bit.lshift; |
| 17 local rshift = bit.rshift; | 17 local rshift = bit.rshift; |
| 18 local unpack = table.unpack or unpack; -- luacheck: ignore 113 | 18 local unpack = table.unpack or unpack; -- luacheck: ignore 113 |
| 19 | 19 |
| 20 local t_concat = table.concat; | 20 local t_concat = table.concat; |
| 21 local s_byte = string.byte; | |
| 22 local s_char= string.char; | 21 local s_char= string.char; |
| 23 local s_sub = string.sub; | |
| 24 local s_pack = string.pack; | 22 local s_pack = string.pack; |
| 25 local s_unpack = string.unpack; | 23 local s_unpack = string.unpack; |
| 26 | 24 |
| 27 if not s_pack and softreq"struct" then | 25 if not s_pack and softreq"struct" then |
| 28 s_pack = softreq"struct".pack; | 26 s_pack = softreq"struct".pack; |
| 29 s_unpack = softreq"struct".unpack; | 27 s_unpack = softreq"struct".unpack; |
| 30 end | 28 end |
| 31 | 29 |
| 32 local function read_uint16be(str, pos) | 30 local function read_uint16be(str, pos) |
| 33 local l1, l2 = s_byte(str, pos, pos+1); | 31 local l1, l2 = str:byte(pos, pos+1); |
| 34 return l1*256 + l2; | 32 return l1*256 + l2; |
| 35 end | 33 end |
| 36 -- FIXME: this may lose precision | 34 -- FIXME: this may lose precision |
| 37 local function read_uint64be(str, pos) | 35 local function read_uint64be(str, pos) |
| 38 local l1, l2, l3, l4, l5, l6, l7, l8 = s_byte(str, pos, pos+7); | 36 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; | 37 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; | 38 local l = lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8; |
| 41 return h * 2^32 + l; | 39 return h * 2^32 + l; |
| 42 end | 40 end |
| 43 local function pack_uint16be(x) | 41 local function pack_uint16be(x) |
| 61 end | 59 end |
| 62 end | 60 end |
| 63 | 61 |
| 64 if s_unpack then | 62 if s_unpack then |
| 65 function read_uint16be(str, pos) | 63 function read_uint16be(str, pos) |
| 64 if type(str) ~= "string" then | |
| 65 str, pos = str:sub(pos, pos+1), 1; | |
| 66 end | |
| 66 return s_unpack(">I2", str, pos); | 67 return s_unpack(">I2", str, pos); |
| 67 end | 68 end |
| 68 function read_uint64be(str, pos) | 69 function read_uint64be(str, pos) |
| 70 if type(str) ~= "string" then | |
| 71 str, pos = str:sub(pos, pos+7), 1; | |
| 72 end | |
| 69 return s_unpack(">I8", str, pos); | 73 return s_unpack(">I8", str, pos); |
| 70 end | 74 end |
| 71 end | 75 end |
| 72 | 76 |
| 73 local function parse_frame_header(frame) | 77 local function parse_frame_header(frame) |
| 74 if #frame < 2 then return; end | 78 if #frame < 2 then return; end |
| 75 | 79 |
| 76 local byte1, byte2 = s_byte(frame, 1, 2); | 80 local byte1, byte2 = frame:byte(1, 2); |
| 77 local result = { | 81 local result = { |
| 78 FIN = band(byte1, 0x80) > 0; | 82 FIN = band(byte1, 0x80) > 0; |
| 79 RSV1 = band(byte1, 0x40) > 0; | 83 RSV1 = band(byte1, 0x40) > 0; |
| 80 RSV2 = band(byte1, 0x20) > 0; | 84 RSV2 = band(byte1, 0x20) > 0; |
| 81 RSV3 = band(byte1, 0x10) > 0; | 85 RSV3 = band(byte1, 0x10) > 0; |
| 100 elseif length_bytes == 8 then | 104 elseif length_bytes == 8 then |
| 101 result.length = read_uint64be(frame, 3); | 105 result.length = read_uint64be(frame, 3); |
| 102 end | 106 end |
| 103 | 107 |
| 104 if result.MASK then | 108 if result.MASK then |
| 105 result.key = { s_byte(frame, length_bytes+3, length_bytes+6) }; | 109 result.key = { frame:byte(length_bytes+3, length_bytes+6) }; |
| 106 end | 110 end |
| 107 | 111 |
| 108 return result, header_length; | 112 return result, header_length; |
| 109 end | 113 end |
| 110 | 114 |
| 119 local counter = 0; | 123 local counter = 0; |
| 120 local data = {}; | 124 local data = {}; |
| 121 for i = from, to do | 125 for i = from, to do |
| 122 local key_index = counter%key_len + 1; | 126 local key_index = counter%key_len + 1; |
| 123 counter = counter + 1; | 127 counter = counter + 1; |
| 124 data[counter] = s_char(bxor(key[key_index], s_byte(str, i))); | 128 data[counter] = s_char(bxor(key[key_index], str:byte(i))); |
| 125 end | 129 end |
| 126 return t_concat(data); | 130 return t_concat(data); |
| 127 end | 131 end |
| 128 | 132 |
| 129 local function parse_frame_body(frame, header, pos) | 133 local function parse_frame_body(frame, header, pos) |
| 134 end | 138 end |
| 135 end | 139 end |
| 136 | 140 |
| 137 local function parse_frame(frame) | 141 local function parse_frame(frame) |
| 138 local result, pos = parse_frame_header(frame); | 142 local result, pos = parse_frame_header(frame); |
| 139 if result == nil or #frame < (pos + result.length) then return; end | 143 if result == nil or #frame < (pos + result.length) then return nil, nil, result; end |
| 140 result.data = parse_frame_body(frame, result, pos+1); | 144 result.data = parse_frame_body(frame, result, pos+1); |
| 141 return result, pos + result.length; | 145 return result, pos + result.length; |
| 142 end | 146 end |
| 143 | 147 |
| 144 local function build_frame(desc) | 148 local function build_frame(desc) |
| 187 local function parse_close(data) | 191 local function parse_close(data) |
| 188 local code, message | 192 local code, message |
| 189 if #data >= 2 then | 193 if #data >= 2 then |
| 190 code = read_uint16be(data, 1); | 194 code = read_uint16be(data, 1); |
| 191 if #data > 2 then | 195 if #data > 2 then |
| 192 message = s_sub(data, 3); | 196 message = data:sub(3); |
| 193 end | 197 end |
| 194 end | 198 end |
| 195 return code, message | 199 return code, message |
| 196 end | 200 end |
| 197 | 201 |
