mod_websocket/mod_websocket.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 07 Jun 2013 14:29:01 +0100
changeset 1057 0b41122b19f9
parent 1029 9d85aded2fb6
child 1193 bbe278a56b0a
permissions -rw-r--r--
mod_muc_limits: Abort loading on non-MUC hosts (thanks Ge0rG)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     1
-- Prosody IM
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     2
-- Copyright (C) 2012 Florian Zeitz
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     3
--
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     5
-- COPYING file in the source package for more information.
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     6
--
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     7
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
     8
module:set_global();
129
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
     9
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    10
local add_filter = require "util.filters".add_filter;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
    11
local sha1 = require "util.hashes".sha1;
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
    12
local base64 = require "util.encodings".base64.encode;
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    13
local softreq = require "util.dependencies".softreq;
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    14
local portmanager = require "core.portmanager";
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
    15
905
eae665bc2122 mod_websocket: Fix require to work with lua-bitop (Thanks István and Zash)
Florian Zeitz <florob@babelmonkeys.de>
parents: 895
diff changeset
    16
local bit;
eae665bc2122 mod_websocket: Fix require to work with lua-bitop (Thanks István and Zash)
Florian Zeitz <florob@babelmonkeys.de>
parents: 895
diff changeset
    17
pcall(function() bit = require"bit"; end);
eae665bc2122 mod_websocket: Fix require to work with lua-bitop (Thanks István and Zash)
Florian Zeitz <florob@babelmonkeys.de>
parents: 895
diff changeset
    18
bit = bit or softreq"bit32"
eae665bc2122 mod_websocket: Fix require to work with lua-bitop (Thanks István and Zash)
Florian Zeitz <florob@babelmonkeys.de>
parents: 895
diff changeset
    19
if not bit then module:log("error", "No bit module found. Either LuaJIT 2, lua-bitop or Lua 5.2 is required"); end
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    20
local band = bit.band;
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    21
local bxor = bit.bxor;
910
c469a2b2d77d mod_websocket: Avoid floating point division
Florian Zeitz <florob@babelmonkeys.de>
parents: 909
diff changeset
    22
local rshift = bit.rshift;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
    23
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    24
local t_concat = table.concat;
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    25
local s_byte = string.byte;
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    26
local s_char= string.char;
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    27
856
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    28
local cross_domain = module:get_option("cross_domain_websocket");
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    29
if cross_domain then
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    30
	if cross_domain == true then
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    31
		cross_domain = "*";
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    32
	elseif type(cross_domain) == "table" then
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    33
		cross_domain = t_concat(cross_domain, ", ");
856
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    34
	end
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    35
	if type(cross_domain) ~= "string" then
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    36
		cross_domain = nil;
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    37
	end
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    38
end
7eb54ed58856 mod_websocket: Add CORS support
Florian Zeitz <florob@babelmonkeys.de>
parents: 853
diff changeset
    39
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    40
module:depends("c2s")
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    41
local sessions = module:shared("c2s/sessions");
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
    42
local c2s_listener = portmanager.get_service("c2s").listener;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
    43
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    44
-- Websocket helpers
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    45
local function parse_frame(frame)
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    46
	local result = {};
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    47
	local pos = 1;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    48
	local length_bytes = 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    49
	local tmp_byte;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    50
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    51
	if #frame < 2 then return; end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    52
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    53
	tmp_byte = s_byte(frame, pos);
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    54
	result.FIN = band(tmp_byte, 0x80) > 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    55
	result.RSV1 = band(tmp_byte, 0x40) > 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    56
	result.RSV2 = band(tmp_byte, 0x20) > 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    57
	result.RSV3 = band(tmp_byte, 0x10) > 0;
690
5acc203972f3 mod_websocket: Add fragmentation support
Florian Zeitz <florob@babelmonkeys.de>
parents: 689
diff changeset
    58
	result.opcode = band(tmp_byte, 0x0F);
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    59
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    60
	pos = pos + 1;
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    61
	tmp_byte = s_byte(frame, pos);
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    62
	result.MASK = band(tmp_byte, 0x80) > 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    63
	result.length = band(tmp_byte, 0x7F);
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    64
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    65
	if result.length == 126 then
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    66
		length_bytes = 2;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    67
		result.length = 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    68
	elseif result.length == 127 then
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    69
		length_bytes = 8;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    70
		result.length = 0;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    71
	end
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    72
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    73
	if #frame < (2 + length_bytes) then return; end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    74
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    75
	for i = 1, length_bytes do
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    76
		pos = pos + 1;
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    77
		result.length = result.length * 256 + s_byte(frame, pos);
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    78
	end
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    79
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    80
	if #frame < (2 + length_bytes + (result.MASK and 4 or 0) + result.length) then return; end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    81
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    82
	if result.MASK then
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
    83
		local counter = 0;
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
    84
		local data = {};
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
    85
		local key = {s_byte(frame, pos+1), s_byte(frame, pos+2),
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
    86
				s_byte(frame, pos+3), s_byte(frame, pos+4)}
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
    87
		result.key = key;
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    88
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    89
		pos = pos + 5;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    90
		for i = pos, pos + result.length - 1 do
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
    91
			data[#data+1] = s_char(bxor(key[counter+1], s_byte(frame, i)));
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    92
			counter = (counter + 1) % 4;
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    93
		end
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
    94
		result.data = t_concat(data, "");
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    95
	else
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    96
		result.data = frame:sub(pos + 1, pos + result.length);
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    97
	end
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
    98
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
    99
	return result, 2 + length_bytes + (result.MASK and 4 or 0) + result.length;
677
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
   100
end
eeb41cd5e9f3 mod_websocket: Move frame handling into a separate function
Florian Zeitz <florob@babelmonkeys.de>
parents: 676
diff changeset
   101
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   102
local function build_frame(desc)
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   103
	local length;
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   104
	local result = {};
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   105
	local data = desc.data or "";
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   106
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   107
	result[#result+1] = s_char(0x80 * (desc.FIN and 1 or 0) + desc.opcode);
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   108
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   109
	length = #data;
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   110
	if length <= 125 then -- 7-bit length
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   111
		result[#result+1] = s_char(length);
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   112
	elseif length <= 0xFFFF then -- 2-byte length
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   113
		result[#result+1] = s_char(126);
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   114
		result[#result+1] = s_char(rshift(length, 8)) .. s_char(length%0x100);
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   115
	else -- 8-byte length
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   116
		result[#result+1] = s_char(127);
1025
b56a9aa171b3 mod_websocket: Fix length calculation
Florian Zeitz <florob@babelmonkeys.de>
parents: 969
diff changeset
   117
		local length_bytes = {};
b56a9aa171b3 mod_websocket: Fix length calculation
Florian Zeitz <florob@babelmonkeys.de>
parents: 969
diff changeset
   118
		for i = 8, 1, -1 do
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
   119
			length_bytes[i] = s_char(length % 0x100);
1025
b56a9aa171b3 mod_websocket: Fix length calculation
Florian Zeitz <florob@babelmonkeys.de>
parents: 969
diff changeset
   120
			length = rshift(length, 8);
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   121
		end
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   122
		result[#result+1] = t_concat(length_bytes, "");
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   123
	end
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   124
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   125
	result[#result+1] = data;
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   126
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   127
	return t_concat(result, "");
687
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   128
end
d141375ece4b mod_websocket: Move frame building into a function
Florian Zeitz <florob@babelmonkeys.de>
parents: 677
diff changeset
   129
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   130
--- Filter stuff
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   131
function handle_request(event, path)
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   132
	local request, response = event.request, event.response;
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   133
	local conn = response.conn;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   134
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   135
	if not request.headers.sec_websocket_key then
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   136
		response.headers.content_type = "text/html";
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   137
		return [[<!DOCTYPE html><html><head><title>Websocket</title></head><body>
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   138
			<p>It works! Now point your WebSocket client to this URL to connect to Prosody.</p>
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   139
			</body></html>]];
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   140
	end
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   141
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   142
	local wants_xmpp = false;
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   143
	(request.headers.sec_websocket_protocol or ""):gsub("([^,]*),?", function (proto)
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   144
		if proto == "xmpp" then wants_xmpp = true; end
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   145
	end);
129
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
   146
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   147
	if not wants_xmpp then
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   148
		return 501;
129
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
   149
	end
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
   150
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   151
	local function websocket_close(code, message)
1026
e254cf49e14d mod_websocket: Call string and table functions through locals
Florian Zeitz <florob@babelmonkeys.de>
parents: 1025
diff changeset
   152
		local data = s_char(rshift(code, 8)) .. s_char(code%0x100) .. message;
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   153
		conn:write(build_frame({opcode = 0x8, FIN = true, data = data}));
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   154
		conn:close();
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   155
	end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   156
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   157
	local dataBuffer;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   158
	local function handle_frame(frame)
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   159
		local opcode = frame.opcode;
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   160
		local length = frame.length;
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   161
		module:log("debug", "Websocket received: %s (%i bytes)", frame.data, #frame.data);
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   162
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   163
		-- Error cases
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   164
		if frame.RSV1 or frame.RSV2 or frame.RSV3 then -- Reserved bits non zero
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   165
			websocket_close(1002, "Reserved bits not zero");
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   166
			return false;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   167
		end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   168
1029
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   169
		if opcode == 0x8 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   170
			if length == 1 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   171
				websocket_close(1002, "Close frame with payload, but too short for status code");
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   172
				return false;
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   173
			elseif length >= 2 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   174
				local status_code = s_byte(frame.data, 1) * 256 + s_byte(frame.data, 2)
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   175
				if status_code < 1000 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   176
					websocket_close(1002, "Closed with invalid status code");
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   177
					return false;
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   178
				elseif ((status_code > 1003 and status_code < 1007) or status_code > 1011) and status_code < 3000 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   179
					websocket_close(1002, "Cosed with reserved status code");
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   180
					return false;
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   181
				end
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   182
			end
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   183
		end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   184
1029
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   185
		if opcode >= 0x8 then
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   186
			if length > 125 then -- Control frame with too much payload
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   187
				websocket_close(1002, "Payload too large");
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   188
				return false;
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   189
			end
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   190
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   191
			if not frame.FIN then -- Fragmented control frame
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   192
				websocket_close(1002, "Fragmented control frame");
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   193
				return false;
9d85aded2fb6 mod_websocket: Add some more error checks for close frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 1028
diff changeset
   194
			end
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   195
		end
690
5acc203972f3 mod_websocket: Add fragmentation support
Florian Zeitz <florob@babelmonkeys.de>
parents: 689
diff changeset
   196
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   197
		if (opcode > 0x2 and opcode < 0x8) or (opcode > 0xA) then
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   198
			websocket_close(1002, "Reserved opcode");
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   199
			return false;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   200
		end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   201
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   202
		if opcode == 0x0 and not dataBuffer then
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   203
			websocket_close(1002, "Unexpected continuation frame");
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   204
			return false;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   205
		end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   206
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   207
		if (opcode == 0x1 or opcode == 0x2) and dataBuffer then
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   208
			websocket_close(1002, "Continuation frame expected");
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   209
			return false;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   210
		end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   211
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   212
		-- Valid cases
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   213
		if opcode == 0x0 then -- Continuation frame
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   214
			dataBuffer[#dataBuffer+1] = frame.data;
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   215
		elseif opcode == 0x1 then -- Text frame
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   216
			dataBuffer = {frame.data};
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   217
		elseif opcode == 0x2 then -- Binary frame
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   218
			websocket_close(1003, "Only text frames are supported");
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   219
			return;
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   220
		elseif opcode == 0x8 then -- Close request
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   221
			websocket_close(1000, "Goodbye");
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   222
			return;
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   223
		elseif opcode == 0x9 then -- Ping frame
691
04662cc35280 mod_websocket: Answer ping frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 690
diff changeset
   224
			frame.opcode = 0xA;
04662cc35280 mod_websocket: Answer ping frames
Florian Zeitz <florob@babelmonkeys.de>
parents: 690
diff changeset
   225
			conn:write(build_frame(frame));
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   226
			return "";
690
5acc203972f3 mod_websocket: Add fragmentation support
Florian Zeitz <florob@babelmonkeys.de>
parents: 689
diff changeset
   227
		else
1028
81065638299d mod_websocket: Access some values via locales instead of through tables
Florian Zeitz <florob@babelmonkeys.de>
parents: 1027
diff changeset
   228
			log("warn", "Received frame with unsupported opcode %i", opcode);
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   229
			return "";
690
5acc203972f3 mod_websocket: Add fragmentation support
Florian Zeitz <florob@babelmonkeys.de>
parents: 689
diff changeset
   230
		end
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   231
690
5acc203972f3 mod_websocket: Add fragmentation support
Florian Zeitz <florob@babelmonkeys.de>
parents: 689
diff changeset
   232
		if frame.FIN then
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   233
			local data = t_concat(dataBuffer, "");
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   234
			dataBuffer = nil;
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   235
			return data;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   236
		end
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   237
		return "";
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   238
	end
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   239
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   240
	conn:setlistener(c2s_listener);
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   241
	c2s_listener.onconnect(conn);
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   242
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   243
	local frameBuffer = "";
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   244
	add_filter(sessions[conn], "bytes/in", function(data)
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   245
		local cache = {};
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   246
		frameBuffer = frameBuffer .. data;
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   247
		local frame, length = parse_frame(frameBuffer);
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   248
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   249
		while frame do
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   250
			frameBuffer = frameBuffer:sub(length + 1);
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   251
			local result = handle_frame(frame);
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   252
			if not result then return; end
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   253
			cache[#cache+1] = result;
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   254
			frame, length = parse_frame(frameBuffer);
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   255
		end
1027
6a2dfa8af421 mod_websocket: Optimize string concatenation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1026
diff changeset
   256
		return t_concat(cache, "");
844
a0987c0e4e1d mod_websocket: Check whether the xmpp sub-protocol was requested
Florian Zeitz <florob@babelmonkeys.de>
parents: 842
diff changeset
   257
	end);
a0987c0e4e1d mod_websocket: Check whether the xmpp sub-protocol was requested
Florian Zeitz <florob@babelmonkeys.de>
parents: 842
diff changeset
   258
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   259
	add_filter(sessions[conn], "bytes/out", function(data)
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   260
		return build_frame({ FIN = true, opcode = 0x01, data = tostring(data)});
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   261
	end);
842
32df4d13f178 mod_websocket: More robust frame handling
Florian Zeitz <florob@babelmonkeys.de>
parents: 840
diff changeset
   262
969
8eba9d4809d2 mod_websocket: Set status_code instead of status
Florian Zeitz <florob@babelmonkeys.de>
parents: 910
diff changeset
   263
	response.status_code = 101;
895
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   264
	response.headers.upgrade = "websocket";
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   265
	response.headers.connection = "Upgrade";
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   266
	response.headers.sec_webSocket_accept = base64(sha1(request.headers.sec_websocket_key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   267
	response.headers.sec_webSocket_protocol = "xmpp";
1f4d77104da5 mod_websocket: Simplify by getting the c2s_listener from mod_c2s
Florian Zeitz <florob@babelmonkeys.de>
parents: 857
diff changeset
   268
	response.headers.access_control_allow_origin = cross_domain;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   269
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   270
	return "";
129
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
   271
end
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   272
688
e87678a52720 mod_websocket: Make this a shared module
Florian Zeitz <florob@babelmonkeys.de>
parents: 687
diff changeset
   273
function module.add_host(module)
e87678a52720 mod_websocket: Make this a shared module
Florian Zeitz <florob@babelmonkeys.de>
parents: 687
diff changeset
   274
	module:depends("http");
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   275
	module:provides("http", {
909
ec4c6e8f277d mod_websocket: Change the HTTP name to websocket, and override the default_path instead
Florian Zeitz <florob@babelmonkeys.de>
parents: 905
diff changeset
   276
		name = "websocket";
ec4c6e8f277d mod_websocket: Change the HTTP name to websocket, and override the default_path instead
Florian Zeitz <florob@babelmonkeys.de>
parents: 905
diff changeset
   277
		default_path = "xmpp-websocket";
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   278
		route = {
849
6e2ec1825182 mod_websocket: Accept GET request without trailing /
Florian Zeitz <florob@babelmonkeys.de>
parents: 844
diff changeset
   279
			["GET"] = handle_request;
6e2ec1825182 mod_websocket: Accept GET request without trailing /
Florian Zeitz <florob@babelmonkeys.de>
parents: 844
diff changeset
   280
			["GET /"] = handle_request;
676
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   281
		};
54fa9d6d7809 mod_websocket: New mod_c2s based version, still WIP
Florian Zeitz <florob@babelmonkeys.de>
parents: 129
diff changeset
   282
	});
129
5fc00a3e47b5 mod_websocket: Initial commit
Ali Sabil <ali.sabil@gmail.com>
parents:
diff changeset
   283
end