Software /
code /
prosody
Comparison
net/websocket.lua @ 6396:17b54f523796
Check Sec-WebSocket-Protocol header
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Fri, 05 Sep 2014 02:14:04 +0200 |
parent | 6395:e0164b0fcafd |
child | 6398:ad434f47bfc0 |
comparison
equal
deleted
inserted
replaced
6395:e0164b0fcafd | 6396:17b54f523796 |
---|---|
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 local t_concat = table.concat; | |
10 | |
9 local http = require "net.http"; | 11 local http = require "net.http"; |
10 local frames = require "net.websocket.frames"; | 12 local frames = require "net.websocket.frames"; |
11 local base64 = require "util.encodings".base64; | 13 local base64 = require "util.encodings".base64; |
12 local sha1 = require "util.hashes".sha1; | 14 local sha1 = require "util.hashes".sha1; |
13 local random_bytes = require "util.random".bytes; | 15 local random_bytes = require "util.random".bytes; |
74 return fail(s, 1002, "Reserved opcode"); | 76 return fail(s, 1002, "Reserved opcode"); |
75 end | 77 end |
76 if frame.FIN then | 78 if frame.FIN then |
77 s.databuffer = nil; | 79 s.databuffer = nil; |
78 if s.onmessage then | 80 if s.onmessage then |
79 s:onmessage(table.concat(databuffer), databuffer.type); | 81 s:onmessage(t_concat(databuffer), databuffer.type); |
80 end | 82 end |
81 end | 83 end |
82 else -- Control frame | 84 else -- Control frame |
83 if frame.length > 125 then -- Control frame with too much payload | 85 if frame.length > 125 then -- Control frame with too much payload |
84 return fail(s, 1002, "Payload too large"); | 86 return fail(s, 1002, "Payload too large"); |
185 ]] | 187 ]] |
186 local key = base64.encode(random_bytes(16)); | 188 local key = base64.encode(random_bytes(16)); |
187 | 189 |
188 -- Either a single protocol string or an array of protocol strings. | 190 -- Either a single protocol string or an array of protocol strings. |
189 local protocol = ex.protocol; | 191 local protocol = ex.protocol; |
190 if type(protocol) == "table" then | 192 if type(protocol) == "string" then |
191 protocol = table.concat(protocol, ", "); | 193 protocol = { protocol }; |
194 end | |
195 for _, v in ipairs(protocol) do | |
196 protocol[v] = true; | |
192 end | 197 end |
193 | 198 |
194 local headers = { | 199 local headers = { |
195 ["Upgrade"] = "websocket"; | 200 ["Upgrade"] = "websocket"; |
196 ["Connection"] = "Upgrade"; | 201 ["Connection"] = "Upgrade"; |
197 ["Sec-WebSocket-Key"] = key; | 202 ["Sec-WebSocket-Key"] = key; |
198 ["Sec-WebSocket-Protocol"] = protocol; | 203 ["Sec-WebSocket-Protocol"] = t_concat(protocol, ", "); |
199 ["Sec-WebSocket-Version"] = "13"; | 204 ["Sec-WebSocket-Version"] = "13"; |
200 ["Sec-WebSocket-Extensions"] = ex.extensions; | 205 ["Sec-WebSocket-Extensions"] = ex.extensions; |
201 } | 206 } |
202 if ex.headers then | 207 if ex.headers then |
203 for k,v in pairs(ex.headers) do | 208 for k,v in pairs(ex.headers) do |
231 }, function(b, c, r, http_req) | 236 }, function(b, c, r, http_req) |
232 if c ~= 101 | 237 if c ~= 101 |
233 or r.headers["connection"]:lower() ~= "upgrade" | 238 or r.headers["connection"]:lower() ~= "upgrade" |
234 or r.headers["upgrade"] ~= "websocket" | 239 or r.headers["upgrade"] ~= "websocket" |
235 or r.headers["sec-websocket-accept"] ~= base64.encode(sha1(key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")) | 240 or r.headers["sec-websocket-accept"] ~= base64.encode(sha1(key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")) |
236 -- TODO: check "Sec-WebSocket-Protocol" | 241 or not protocol[r.headers["sec-websocket-protocol"]] |
237 then | 242 then |
238 s.readyState = 3; | 243 s.readyState = 3; |
239 log("warn", "WebSocket connection to %s failed: %s", url, tostring(b)); | 244 log("warn", "WebSocket connection to %s failed: %s", url, tostring(b)); |
240 if s.onerror then s:onerror("connecting-failed"); end | 245 if s.onerror then s:onerror("connecting-failed"); end |
241 return; | 246 return; |