Software /
code /
prosody-modules
Comparison
mod_websocket/mod_websocket.lua @ 1026:e254cf49e14d
mod_websocket: Call string and table functions through locals
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Thu, 30 May 2013 22:51:12 +0200 |
parent | 1025:b56a9aa171b3 |
child | 1027:6a2dfa8af421 |
comparison
equal
deleted
inserted
replaced
1025:b56a9aa171b3 | 1026:e254cf49e14d |
---|---|
19 if not bit then module:log("error", "No bit module found. Either LuaJIT 2, lua-bitop or Lua 5.2 is required"); end | 19 if not bit then module:log("error", "No bit module found. Either LuaJIT 2, lua-bitop or Lua 5.2 is required"); end |
20 local band = bit.band; | 20 local band = bit.band; |
21 local bxor = bit.bxor; | 21 local bxor = bit.bxor; |
22 local rshift = bit.rshift; | 22 local rshift = bit.rshift; |
23 | 23 |
24 local t_concat = table.concat; | |
25 local s_byte = string.byte; | |
26 local s_char= string.char; | |
27 | |
24 local cross_domain = module:get_option("cross_domain_websocket"); | 28 local cross_domain = module:get_option("cross_domain_websocket"); |
25 if cross_domain then | 29 if cross_domain then |
26 if cross_domain == true then | 30 if cross_domain == true then |
27 cross_domain = "*"; | 31 cross_domain = "*"; |
28 elseif type(cross_domain) == "table" then | 32 elseif type(cross_domain) == "table" then |
29 cross_domain = table.concat(cross_domain, ", "); | 33 cross_domain = t_concat(cross_domain, ", "); |
30 end | 34 end |
31 if type(cross_domain) ~= "string" then | 35 if type(cross_domain) ~= "string" then |
32 cross_domain = nil; | 36 cross_domain = nil; |
33 end | 37 end |
34 end | 38 end |
45 local counter = 0; | 49 local counter = 0; |
46 local tmp_byte; | 50 local tmp_byte; |
47 | 51 |
48 if #frame < 2 then return; end | 52 if #frame < 2 then return; end |
49 | 53 |
50 tmp_byte = string.byte(frame, pos); | 54 tmp_byte = s_byte(frame, pos); |
51 result.FIN = band(tmp_byte, 0x80) > 0; | 55 result.FIN = band(tmp_byte, 0x80) > 0; |
52 result.RSV1 = band(tmp_byte, 0x40) > 0; | 56 result.RSV1 = band(tmp_byte, 0x40) > 0; |
53 result.RSV2 = band(tmp_byte, 0x20) > 0; | 57 result.RSV2 = band(tmp_byte, 0x20) > 0; |
54 result.RSV3 = band(tmp_byte, 0x10) > 0; | 58 result.RSV3 = band(tmp_byte, 0x10) > 0; |
55 result.opcode = band(tmp_byte, 0x0F); | 59 result.opcode = band(tmp_byte, 0x0F); |
56 | 60 |
57 pos = pos + 1; | 61 pos = pos + 1; |
58 tmp_byte = string.byte(frame, pos); | 62 tmp_byte = s_byte(frame, pos); |
59 result.MASK = band(tmp_byte, 0x80) > 0; | 63 result.MASK = band(tmp_byte, 0x80) > 0; |
60 result.length = band(tmp_byte, 0x7F); | 64 result.length = band(tmp_byte, 0x7F); |
61 | 65 |
62 if result.length == 126 then | 66 if result.length == 126 then |
63 length_bytes = 2; | 67 length_bytes = 2; |
69 | 73 |
70 if #frame < (2 + length_bytes) then return; end | 74 if #frame < (2 + length_bytes) then return; end |
71 | 75 |
72 for i = 1, length_bytes do | 76 for i = 1, length_bytes do |
73 pos = pos + 1; | 77 pos = pos + 1; |
74 result.length = result.length * 256 + string.byte(frame, pos); | 78 result.length = result.length * 256 + s_byte(frame, pos); |
75 end | 79 end |
76 | 80 |
77 if #frame < (2 + length_bytes + (result.MASK and 4 or 0) + result.length) then return; end | 81 if #frame < (2 + length_bytes + (result.MASK and 4 or 0) + result.length) then return; end |
78 | 82 |
79 if result.MASK then | 83 if result.MASK then |
80 result.key = {string.byte(frame, pos+1), string.byte(frame, pos+2), | 84 result.key = {s_byte(frame, pos+1), s_byte(frame, pos+2), |
81 string.byte(frame, pos+3), string.byte(frame, pos+4)} | 85 s_byte(frame, pos+3), s_byte(frame, pos+4)} |
82 | 86 |
83 pos = pos + 5; | 87 pos = pos + 5; |
84 result.data = ""; | 88 result.data = ""; |
85 for i = pos, pos + result.length - 1 do | 89 for i = pos, pos + result.length - 1 do |
86 result.data = result.data .. string.char(bxor(result.key[counter+1], string.byte(frame, i))); | 90 result.data = result.data .. s_char(bxor(result.key[counter+1], s_byte(frame, i))); |
87 counter = (counter + 1) % 4; | 91 counter = (counter + 1) % 4; |
88 end | 92 end |
89 else | 93 else |
90 result.data = frame:sub(pos + 1, pos + result.length); | 94 result.data = frame:sub(pos + 1, pos + result.length); |
91 end | 95 end |
96 local function build_frame(desc) | 100 local function build_frame(desc) |
97 local length; | 101 local length; |
98 local result = ""; | 102 local result = ""; |
99 local data = desc.data or ""; | 103 local data = desc.data or ""; |
100 | 104 |
101 result = result .. string.char(0x80 * (desc.FIN and 1 or 0) + desc.opcode); | 105 result = result .. s_char(0x80 * (desc.FIN and 1 or 0) + desc.opcode); |
102 | 106 |
103 length = #data; | 107 length = #data; |
104 if length <= 125 then -- 7-bit length | 108 if length <= 125 then -- 7-bit length |
105 result = result .. string.char(length); | 109 result = result .. s_char(length); |
106 elseif length <= 0xFFFF then -- 2-byte length | 110 elseif length <= 0xFFFF then -- 2-byte length |
107 result = result .. string.char(126); | 111 result = result .. s_char(126); |
108 result = result .. string.char(rshift(length, 8)) .. string.char(length%0x100); | 112 result = result .. s_char(rshift(length, 8)) .. s_char(length%0x100); |
109 else -- 8-byte length | 113 else -- 8-byte length |
110 local length_bytes = {}; | 114 local length_bytes = {}; |
111 result = result .. string.char(127); | 115 result = result .. s_char(127); |
112 for i = 8, 1, -1 do | 116 for i = 8, 1, -1 do |
113 length_bytes[i] = string.char(length % 0x100); | 117 length_bytes[i] = s_char(length % 0x100); |
114 length = rshift(length, 8); | 118 length = rshift(length, 8); |
115 end | 119 end |
116 result = result .. table.concat(length_bytes, ""); | 120 result = result .. t_concat(length_bytes, ""); |
117 end | 121 end |
118 | 122 |
119 result = result .. data; | 123 result = result .. data; |
120 | 124 |
121 return result; | 125 return result; |
141 if not wants_xmpp then | 145 if not wants_xmpp then |
142 return 501; | 146 return 501; |
143 end | 147 end |
144 | 148 |
145 local function websocket_close(code, message) | 149 local function websocket_close(code, message) |
146 local data = string.char(rshift(code, 8)) .. string.char(code%0x100) .. message; | 150 local data = s_char(rshift(code, 8)) .. s_char(code%0x100) .. message; |
147 conn:write(build_frame({opcode = 0x8, FIN = true, data = data})); | 151 conn:write(build_frame({opcode = 0x8, FIN = true, data = data})); |
148 conn:close(); | 152 conn:close(); |
149 end | 153 end |
150 | 154 |
151 local dataBuffer; | 155 local dataBuffer; |