Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions lib/nodejs/lib/thrift/web_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ var log = require("./log");
var MultiplexedProcessor =
require("./multiplexed_processor").MultiplexedProcessor;

function sanitizeHeader(value) {
return (value || "").replace(/[\r\n]/g, "");
}

var TBufferedTransport = require("./buffered_transport");
var TBinaryProtocol = require("./binary_protocol");
var InputBufferUnderrunError = require("./input_buffer_underrun_error");
Expand Down Expand Up @@ -84,7 +88,7 @@ var wsFrame = {
* @returns {Buffer} - The WebSocket frame, ready to send
*/
encode: function (data, mask, binEncoding) {
var frame = new Buffer(wsFrame.frameSizeFromData(data, mask));
var frame = Buffer.alloc(wsFrame.frameSizeFromData(data, mask));
//Byte 0 - FIN & OPCODE
frame[0] =
wsFrame.fin.FIN +
Expand Down Expand Up @@ -171,19 +175,19 @@ var wsFrame = {
}
//MASK
if (wsFrame.mask.TO_SERVER == (frame[1] & wsFrame.mask.TO_SERVER)) {
result.mask = new Buffer(4);
result.mask = Buffer.alloc(4);
frame.copy(result.mask, 0, dataOffset, dataOffset + 4);
dataOffset += 4;
}
//Payload
result.data = new Buffer(len);
result.data = Buffer.alloc(len);
frame.copy(result.data, 0, dataOffset, dataOffset + len);
if (result.mask) {
wsFrame.applyMask(result.data, result.mask);
}
//Next Frame
if (frame.length > dataOffset + len) {
result.nextFrame = new Buffer(frame.length - (dataOffset + len));
result.nextFrame = Buffer.alloc(frame.length - (dataOffset + len));
frame.copy(result.nextFrame, 0, dataOffset + len, frame.length);
}
//Don't forward control frames
Expand Down Expand Up @@ -450,7 +454,8 @@ exports.createWebServer = function (options) {
var filename = path.resolve(path.join(baseDir, uri));

//Ensure the basedir path is not able to be escaped
if (filename.indexOf(baseDir) != 0) {
var normalizedBase = baseDir.endsWith(path.sep) ? baseDir : baseDir + path.sep;
if (filename !== baseDir && filename.indexOf(normalizedBase) !== 0) {
response.writeHead(400, "Invalid request path", {});
response.end();
return;
Expand Down Expand Up @@ -543,6 +548,14 @@ exports.createWebServer = function (options) {
}
})
.on("upgrade", function (request, socket, head) {
//Verify CORS origin for WebSocket upgrades
if (request.headers.origin && options.cors) {
if (!options.cors["*"] && !options.cors[request.headers.origin]) {
socket.write("HTTP/1.1 403 Origin not allowed\r\n\r\n");
socket.destroy();
return;
}
}
//Lookup service
var svc;
try {
Expand All @@ -557,6 +570,9 @@ exports.createWebServer = function (options) {
request.headers["sec-websocket-key"] +
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
);
var origin = sanitizeHeader(request.headers.origin);
var host = sanitizeHeader(request.headers.host);
var reqUrl = sanitizeHeader(request.url);
socket.write(
"HTTP/1.1 101 Switching Protocols\r\n" +
"Upgrade: websocket\r\n" +
Expand All @@ -565,11 +581,11 @@ exports.createWebServer = function (options) {
hash.digest("base64") +
"\r\n" +
"Sec-WebSocket-Origin: " +
request.headers.origin +
origin +
"\r\n" +
"Sec-WebSocket-Location: ws://" +
request.headers.host +
request.url +
host +
reqUrl +
"\r\n" +
"\r\n",
);
Expand All @@ -582,7 +598,7 @@ exports.createWebServer = function (options) {
//Prepend any existing decoded data
if (data) {
if (result.data) {
var newData = new Buffer(data.length + result.data.length);
var newData = Buffer.alloc(data.length + result.data.length);
data.copy(newData);
result.data.copy(newData, data.length);
result.data = newData;
Expand Down
Loading