NodeJS编写一个Masked WebSocket框架?

时间:2014-11-13 22:46:15

标签: node.js sockets websocket masking

我需要帮助。

使用node.js制作小型聊天应用和服务器

屏蔽和未屏蔽的数据读取eveything ok。 写unmasked数据确定没问题。现在我需要发送屏蔽数据。

需要小修改无掩码数据发送脚本。请帮忙。

我的剧本:

  this.send = function(data) {
    var dataLength = Buffer.byteLength(data),
      dataBuffer, rawBytesSend = 2;
    if(dataLength > 65535) {
      dataBuffer = new Buffer(10 + dataLength);
      dataBuffer[1] = 127;
      var low = dataLength | 0,
        hi = (dataLength - low) / 4294967296;
      dataBuffer[2] = (hi >> 24) & 255;
      dataBuffer[3] = (hi >> 16) & 255;
      dataBuffer[4] = (hi >> 8) & 255;
      dataBuffer[5] = hi & 255;
      dataBuffer[6] = (low >> 24) & 255;
      dataBuffer[7] = (low >> 16) & 255;
      dataBuffer[8] = (low >> 8) & 255;
      dataBuffer[9] = low & 255;
      rawBytesSend += 8
    } else if(dataLength > 125) {
      dataBuffer = new Buffer(4 + dataLength);
      dataBuffer[1] = 126;
      dataBuffer[2] = (dataLength >> 8) & 255;
      dataBuffer[3] = dataLength & 255;
      rawBytesSend += 2
    } else {
      dataBuffer = new Buffer(2 + dataLength);
      dataBuffer[1] = dataLength
    }
    dataBuffer[0] = 128 + (binary ? 2 : 1);
    dataBuffer[1] &= ~128;


    /* NOT WOKING THIS CODE BLOCK <<<<------
    mask = [Math.floor(Math.random() * 256), Math.floor(Math.random() * 256),
            Math.floor(Math.random() * 256), Math.floor(Math.random() * 256)];

    for (var i = 0, n = dataBuffer.length - rawBytesSend ; i < n; i++) {
      dataBuffer[rawBytesSend + i] = dataBuffer[rawBytesSend + i] ^ mask[i % 4];
    }
    */ //NOT WOKING THIS CODE BLOCK HOW TO FIX THIS PROBLEM !!!!!!!!!!!!!


    if(that.socket.writable) {
      dataBuffer.write(data, rawBytesSend);
      this.socket.write(dataBuffer);
      that.rawBytesSend += rawBytesSend + dataLength;
      that.bytesSend += dataLength
    } else {
      this.__end(true)
    }
    return rawBytesSend
  };

1 个答案:

答案 0 :(得分:0)

我找到了修复共享...

this.mask = function(payload, mask, offset) {
if (!mask || mask.length === 0) return payload;
offset = offset || 0;
for (var i = 0, n = payload.length - offset; i < n; i++) {
  payload[offset + i] = payload[offset + i] ^ mask[i % 4];
}
return payload;
};

this.send = function(data) {
if (data instanceof Array) data = new Buffer(data);
var code,
    type    ='text',
    _masking=this._mask, 
    OPCODES ={continuation:0,text:1,binary:2,close:8,ping:9,pong:10},

    isText = (typeof data === 'string'),
    opcode = OPCODES[type || (isText ? 'text' : 'binary')],
    buffer = isText ? new Buffer(data, 'utf8') : data,
    insert = code ? 2 : 0,
    length = buffer.length + insert,
    header = (length <= 125) ? 2 : (length <= 65535 ? 4 : 10),
    offset = header + (_masking ? 4 : 0),
    masked = _masking ? 128 : 0,
    frame  = new Buffer(length + offset),
    BYTE   = 255,
    mask, i;

frame[0] = 128 | opcode;

if (length <= 125) {
  frame[1] = masked | length;
} else if (length <= 65535) {
  frame[1] = masked | 126;
  frame[2] = Math.floor(length / 256);
  frame[3] = length & BYTE;
} else {
  frame[1] = masked | 127;
  frame[2] = Math.floor(length / Math.pow(2,56)) & BYTE;
  frame[3] = Math.floor(length / Math.pow(2,48)) & BYTE;
  frame[4] = Math.floor(length / Math.pow(2,40)) & BYTE;
  frame[5] = Math.floor(length / Math.pow(2,32)) & BYTE;
  frame[6] = Math.floor(length / Math.pow(2,24)) & BYTE;
  frame[7] = Math.floor(length / Math.pow(2,16)) & BYTE;
  frame[8] = Math.floor(length / Math.pow(2,8))  & BYTE;
  frame[9] = length & BYTE;
}
if (code) {
  frame[offset]   = Math.floor(code / 256) & BYTE;
  frame[offset+1] = code & BYTE;
}
buffer.copy(frame, offset + insert);
if (_masking) {
  mask = [Math.floor(Math.random() * 256), Math.floor(Math.random() * 256),
          Math.floor(Math.random() * 256), Math.floor(Math.random() * 256)];
  new Buffer(mask).copy(frame, header);
  this.mask(frame, mask, offset);
}
if(that.socket.writable) {
  //dataBuffer.write(data, rawBytesSend);
  this.socket.write(frame);
  //that.rawBytesSend += rawBytesSend + dataLength;
  //that.bytesSend += dataLength
} else {
  this.__end(true)
}
return true;
};