diff --git a/biz/webui/cgi-bin/composer.js b/biz/webui/cgi-bin/composer.js index 942d21ba5..3e20473f3 100644 --- a/biz/webui/cgi-bin/composer.js +++ b/biz/webui/cgi-bin/composer.js @@ -262,7 +262,9 @@ module.exports = function(req, res) { headers.connection = 'Upgrade'; headers.upgrade = headers.upgrade || 'websocket'; headers['sec-websocket-version'] = 13; - headers['sec-websocket-key'] = crypto.randomBytes(16).toString('base64'); + if (common.isWebSocket(headers)) { + headers['sec-websocket-key'] = crypto.randomBytes(16).toString('base64'); + } } else { headers.connection = 'close'; delete headers.upgrade; diff --git a/lib/https/index.js b/lib/https/index.js index 818277b73..efbae8f78 100644 --- a/lib/https/index.js +++ b/lib/https/index.js @@ -34,6 +34,7 @@ var tunnelTmplData = new LRU({ max: 3000, maxAge: 30000 }); var TIMEOUT = 6000; var CONN_TIMEOUT = 60000; var X_RE = /^x/; +var PROTO_SEP_RE = /,\s*/; var proxy, server; function handleWebsocket(socket, clientIp, clientPort) { @@ -49,11 +50,22 @@ function handleWebsocket(socket, clientIp, clientPort) { pluginMgr.resolvePipePlugin(socket, function () { socket.rules = rules.initRules(socket); rules.resolveRulesFile(socket, function () { + socket.isWebSocket = util.isWebSocket(socket.headers) || socket.enable.websocket; resolveWebsocket(socket, wss); }); }); } +function getTransProto(str) { + if (!str || typeof str !== 'string') { + return; + } + if (str.indexOf(',') === -1) { + return str; + } + return str.trim().split(PROTO_SEP_RE)[0]; +} + function resolveWebsocket(socket, wss) { var headers = socket.headers; var reqEmitter = new EventEmitter(); @@ -112,16 +124,18 @@ function resolveWebsocket(socket, wss) { var isSuccess = status == 101; if (isSuccess) { statusMsg = 'HTTP/1.1 101 Switching Protocols'; - var protocol = (headers['sec-websocket-protocol'] || '').split(/, */); - var key = - headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; - key = crypto.createHash('sha1').update(key, 'binary').digest('base64'); - resHeaders['Sec-WebSocket-Accept'] = key; - resHeaders.Upgrade = 'websocket'; - resHeaders.Connection = 'Upgrade'; - if (protocol[0]) { - resHeaders['Sec-WebSocket-Protocol'] = protocol[0]; + var key = headers['sec-websocket-key']; + var protocol = getTransProto(headers['sec-websocket-protocol']); + var upgrade = getTransProto(headers.upgrade); + if (key) { + key += '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; + resHeaders['Sec-WebSocket-Accept'] = crypto.createHash('sha1').update(key, 'binary').digest('base64'); } + if (protocol) { + resHeaders['Sec-WebSocket-Protocol'] = protocol; + } + resHeaders.Upgrade = upgrade || 'websocket'; + resHeaders.Connection = 'Upgrade'; reqSocket = util.getEmptyRes(); reqSocket.headers = resHeaders; socketMgr.handleUpgrade(socket, reqSocket); diff --git a/lib/util/index.js b/lib/util/index.js index 6a4fc4bd5..509e2c339 100644 --- a/lib/util/index.js +++ b/lib/util/index.js @@ -135,6 +135,7 @@ exports.removeProtocol = removeProtocol; exports.setProtocol = common.setProtocol; exports.getProtocol = common.getProtocol; exports.replaceProtocol = common.replaceProtocol; +exports.isWebSocket = common.isWebSocket; exports.wrapRuleValue = common.wrapRuleValue; exports.workerIndex = workerIndex; exports.proc = proc;