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
parents b56a9aa171b3
children 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;