Mercurial > prosody-hg
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 |
| parents | e0164b0fcafd |
| children | 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; |
