Software /
code /
prosody
Comparison
net/websocket/frames.lua @ 11166:51e5149ed0ad
Merge 0.11->trunk
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 15 Oct 2020 14:25:09 +0100 |
parent | 11158:3a72cb126d6c |
parent | 11164:4e5a2af9dd19 |
child | 12386:2d3080d02960 |
comparison
equal
deleted
inserted
replaced
11161:f51ed2652602 | 11166:51e5149ed0ad |
---|---|
10 local random_bytes = require "util.random".bytes; | 10 local random_bytes = require "util.random".bytes; |
11 | 11 |
12 local bit = require "util.bitcompat"; | 12 local bit = require "util.bitcompat"; |
13 local band = bit.band; | 13 local band = bit.band; |
14 local bor = bit.bor; | 14 local bor = bit.bor; |
15 local bxor = bit.bxor; | |
16 local lshift = bit.lshift; | 15 local lshift = bit.lshift; |
17 local rshift = bit.rshift; | 16 local rshift = bit.rshift; |
18 local unpack = table.unpack or unpack; -- luacheck: ignore 113 | 17 local sbit = require "util.strbitop"; |
19 | 18 local sxor = sbit.sxor; |
20 local t_concat = table.concat; | 19 |
21 local s_char= string.char; | 20 local s_char= string.char; |
22 local s_pack = string.pack; | 21 local s_pack = string.pack; |
23 local s_unpack = string.unpack; | 22 local s_unpack = string.unpack; |
24 | 23 |
25 if not s_pack and softreq"struct" then | 24 if not s_pack and softreq"struct" then |
104 elseif length_bytes == 8 then | 103 elseif length_bytes == 8 then |
105 result.length = read_uint64be(frame, 3); | 104 result.length = read_uint64be(frame, 3); |
106 end | 105 end |
107 | 106 |
108 if result.MASK then | 107 if result.MASK then |
109 result.key = { frame:byte(length_bytes+3, length_bytes+6) }; | 108 result.key = frame:sub(length_bytes+3, length_bytes+6); |
110 end | 109 end |
111 | 110 |
112 return result, header_length; | 111 return result, header_length; |
113 end | 112 end |
114 | 113 |
115 -- XORs the string `str` with the array of bytes `key` | 114 -- XORs the string `str` with the array of bytes `key` |
116 -- TODO: optimize | 115 -- TODO: optimize |
117 local function apply_mask(str, key, from, to) | 116 local function apply_mask(str, key, from, to) |
118 from = from or 1 | 117 return sxor(str:sub(from or 1, to or -1), key); |
119 if from < 0 then from = #str + from + 1 end -- negative indices | |
120 to = to or #str | |
121 if to < 0 then to = #str + to + 1 end -- negative indices | |
122 local key_len = #key | |
123 local counter = 0; | |
124 local data = {}; | |
125 for i = from, to do | |
126 local key_index = counter%key_len + 1; | |
127 counter = counter + 1; | |
128 data[counter] = s_char(bxor(key[key_index], str:byte(i))); | |
129 end | |
130 return t_concat(data); | |
131 end | 118 end |
132 | 119 |
133 local function parse_frame_body(frame, header, pos) | 120 local function parse_frame_body(frame, header, pos) |
134 if header.MASK then | 121 if header.MASK then |
135 return apply_mask(frame, header.key, pos, pos + header.length - 1); | 122 return apply_mask(frame, header.key, pos, pos + header.length - 1); |
172 length_extra = pack_uint64be(#data); | 159 length_extra = pack_uint64be(#data); |
173 end | 160 end |
174 | 161 |
175 local key = "" | 162 local key = "" |
176 if desc.MASK then | 163 if desc.MASK then |
177 local key_a = desc.key | 164 key = desc.key |
178 if key_a then | 165 if not key then |
179 key = s_char(unpack(key_a, 1, 4)); | |
180 else | |
181 key = random_bytes(4); | 166 key = random_bytes(4); |
182 key_a = {key:byte(1,4)}; | |
183 end | 167 end |
184 b2 = bor(b2, 0x80); | 168 b2 = bor(b2, 0x80); |
185 data = apply_mask(data, key_a); | 169 data = apply_mask(data, key); |
186 end | 170 end |
187 | 171 |
188 return s_char(b1, b2) .. length_extra .. key .. data | 172 return s_char(b1, b2) .. length_extra .. key .. data |
189 end | 173 end |
190 | 174 |