Thu, 25 Dec 2014 10:48:06 +0000
Initial commit. Tortoises are fun.
0
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 | -- Prosody IM |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 | -- Copyright (C) 2012 Florian Zeitz |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 | -- Copyright (C) 2014 Daurnimator |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 | -- |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 | -- This project is MIT/X11 licensed. Please see the |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 | -- COPYING file in the source package for more information. |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 | -- |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 | local softreq = require "util.dependencies".softreq; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 | local log = require "util.logger".init "websocket.frames"; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 | local random_bytes = require "util.random".bytes; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 | local bit; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 | pcall(function() bit = require"bit"; end); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 | bit = bit or softreq"bit32" |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 | if not bit then log("error", "No bit module found. Either LuaJIT 2, lua-bitop or Lua 5.2 is required"); end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 | local band = bit.band; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 | local bor = bit.bor; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 | local bxor = bit.bxor; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 | local lshift = bit.lshift; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 | local rshift = bit.rshift; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 | local t_concat = table.concat; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 | local s_byte = string.byte; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 | local s_char= string.char; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 | local s_sub = string.sub; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 | local function read_uint16be(str, pos) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 | local l1, l2 = s_byte(str, pos, pos+1); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 | return l1*256 + l2; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 | -- FIXME: this may lose precision |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 | local function read_uint64be(str, pos) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 | local l1, l2, l3, l4, l5, l6, l7, l8 = s_byte(str, pos, pos+7); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 | return lshift(l1, 56) + lshift(l2, 48) + lshift(l3, 40) + lshift(l4, 32) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 | + lshift(l5, 24) + lshift(l6, 16) + lshift(l7, 8) + l8; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 | local function pack_uint16be(x) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 | return s_char(rshift(x, 8), band(x, 0xFF)); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 | local function get_byte(x, n) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 | return band(rshift(x, n), 0xFF); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 | local function pack_uint64be(x) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 | return s_char(rshift(x, 56), get_byte(x, 48), get_byte(x, 40), get_byte(x, 32), |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 | get_byte(x, 24), get_byte(x, 16), get_byte(x, 8), band(x, 0xFF)); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 | local function parse_frame_header(frame) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 | if #frame < 2 then return; end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 | local byte1, byte2 = s_byte(frame, 1, 2); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 | local result = { |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 | FIN = band(byte1, 0x80) > 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 | RSV1 = band(byte1, 0x40) > 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 | RSV2 = band(byte1, 0x20) > 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 | RSV3 = band(byte1, 0x10) > 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 | opcode = band(byte1, 0x0F); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 | MASK = band(byte2, 0x80) > 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 | length = band(byte2, 0x7F); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 | }; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 | local length_bytes = 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 | if result.length == 126 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 | length_bytes = 2; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 | elseif result.length == 127 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 | length_bytes = 8; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 | local header_length = 2 + length_bytes + (result.MASK and 4 or 0); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 | if #frame < header_length then return; end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 | if length_bytes == 2 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 | result.length = read_uint16be(frame, 3); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 | elseif length_bytes == 8 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 | result.length = read_uint64be(frame, 3); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 | if result.MASK then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 | result.key = { s_byte(frame, length_bytes+3, length_bytes+6) }; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 | return result, header_length; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 | -- XORs the string `str` with the array of bytes `key` |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 | -- TODO: optimize |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 | local function apply_mask(str, key, from, to) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 | from = from or 1 |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 | if from < 0 then from = #str + from + 1 end -- negative indicies |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 | to = to or #str |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 | if to < 0 then to = #str + to + 1 end -- negative indicies |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 | local key_len = #key |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 | local counter = 0; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 | local data = {}; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 | for i = from, to do |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 | local key_index = counter%key_len + 1; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
99 | counter = counter + 1; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 | data[counter] = s_char(bxor(key[key_index], s_byte(str, i))); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
101 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 | return t_concat(data); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 | local function parse_frame_body(frame, header, pos) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 | if header.MASK then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 | return apply_mask(frame, header.key, pos, pos + header.length - 1); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 | else |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 | return frame:sub(pos, pos + header.length - 1); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
110 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 | local function parse_frame(frame) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 | local result, pos = parse_frame_header(frame); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
115 | if result == nil or #frame < (pos + result.length) then return; end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
116 | result.data = parse_frame_body(frame, result, pos+1); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
117 | return result, pos + result.length; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
118 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
119 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
120 | local function build_frame(desc) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
121 | local data = desc.data or ""; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
122 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
123 | assert(desc.opcode and desc.opcode >= 0 and desc.opcode <= 0xF, "Invalid WebSocket opcode"); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 | if desc.opcode >= 0x8 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
125 | -- RFC 6455 5.5 |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
126 | assert(#data <= 125, "WebSocket control frames MUST have a payload length of 125 bytes or less."); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
127 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
128 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
129 | local b1 = bor(desc.opcode, |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
130 | desc.FIN and 0x80 or 0, |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
131 | desc.RSV1 and 0x40 or 0, |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
132 | desc.RSV2 and 0x20 or 0, |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
133 | desc.RSV3 and 0x10 or 0); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
134 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 | local b2 = #data; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
136 | local length_extra; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
137 | if b2 <= 125 then -- 7-bit length |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
138 | length_extra = ""; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
139 | elseif b2 <= 0xFFFF then -- 2-byte length |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
140 | b2 = 126; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
141 | length_extra = pack_uint16be(#data); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
142 | else -- 8-byte length |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
143 | b2 = 127; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
144 | length_extra = pack_uint64be(#data); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
145 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
146 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
147 | local key = "" |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
148 | if desc.MASK then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 | local key_a = desc.key |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 | if key_a then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
151 | key = s_char(unpack(key_a, 1, 4)); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
152 | else |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
153 | key = random_bytes(4); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
154 | key_a = {key:byte(1,4)}; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
156 | b2 = bor(b2, 0x80); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 | data = apply_mask(data, key_a); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
158 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
159 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
160 | return s_char(b1, b2) .. length_extra .. key .. data |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
162 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 | local function parse_close(data) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
164 | local code, message |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
165 | if #data >= 2 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
166 | code = read_uint16be(data, 1); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
167 | if #data > 2 then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
168 | message = s_sub(data, 3); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
169 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
170 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
171 | return code, message |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
172 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
173 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
174 | local function build_close(code, message, mask) |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
175 | local data = pack_uint16be(code); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
176 | if message then |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
177 | assert(#message<=123, "Close reason must be <=123 bytes"); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
178 | data = data .. message; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
179 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
180 | return build_frame({ |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
181 | opcode = 0x8; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
182 | FIN = true; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
183 | MASK = mask; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
184 | data = data; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
185 | }); |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
186 | end |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
187 | |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
188 | return { |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
189 | parse_header = parse_frame_header; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
190 | parse_body = parse_frame_body; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
191 | parse = parse_frame; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
192 | build = build_frame; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
193 | parse_close = parse_close; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
194 | build_close = build_close; |
d363a6692a10
Initial commit. Tortoises are fun.
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
195 | }; |