proof-of-concept sending packets to client
This commit is contained in:
parent
7fd4c589df
commit
a53cd1b771
3 changed files with 53 additions and 3 deletions
|
@ -8,6 +8,7 @@ const wormhole = new Wormhole({ urls: [ '/hello' ], httpServer });
|
|||
|
||||
wormhole.on('connect', ({ socket, accept, reject }) => {
|
||||
accept();
|
||||
socket.sendText('hello');
|
||||
});
|
||||
|
||||
httpServer.listen(8080);
|
|
@ -14,6 +14,8 @@ class WebsocketFrame {
|
|||
this.MASK = undefined;
|
||||
this.PayloadLen = undefined;
|
||||
|
||||
this.PayloadLenEx = undefined; // This is for when PayloadLen needs to be extended
|
||||
|
||||
// 4 bytes - masking key
|
||||
this.MaskingKey = undefined;
|
||||
|
||||
|
@ -23,6 +25,30 @@ class WebsocketFrame {
|
|||
}
|
||||
}
|
||||
|
||||
WebsocketFrame.prototype.toBuffer = function() {
|
||||
const packet = [];
|
||||
|
||||
const firstByte = this.FIN << 0x07 | this.RSVx << 0x06 | this.Opcode;
|
||||
const secondByte = this.MASK << 0x07 | this.PayloadLen;
|
||||
const headerBuffer = Buffer.from([firstByte, secondByte]);
|
||||
packet.push(headerBuffer);
|
||||
|
||||
let lenBuffer;
|
||||
if (this.PayloadLen === 126) {
|
||||
lenBuffer = Buffer.alloc(2);
|
||||
buf.writeUint16BE(this.PayloadLenEx);
|
||||
} else if (this.PayloadLen === 127) {
|
||||
lenBuffer = Buffer.alloc(8);
|
||||
buf.writeBigUint64BE(this.PayloadLenEx);
|
||||
}
|
||||
lenBuffer && packet.push(lenBuffer);
|
||||
|
||||
this.MASK && packet.push(this.MaskingKey);
|
||||
packet.push(this.PayloadData);
|
||||
|
||||
return Buffer.concat(packet);
|
||||
};
|
||||
|
||||
const parseWebsocketFrame = (data) => {
|
||||
const firstByte = data.getUint8(0);
|
||||
const secondByte = data.getUint8(1);
|
||||
|
@ -42,18 +68,20 @@ const parseWebsocketFrame = (data) => {
|
|||
|
||||
// Handle Payload len cases and set the masking key offset
|
||||
if (frame.PayloadLen === 126) {
|
||||
frame.PayloadLen = data.getUint16(2);
|
||||
frame.PayloadLenEx = data.getUint16(2);
|
||||
maskingKeyOffset = 4; // 4 byte offset, because we also read 2 bytes with getUint16 above (2 bytes (normal size) + 2 bytes)
|
||||
} else if (frame.PayloadLen === 127) {
|
||||
frame.PayloadLen = data.getBigUint64(2);
|
||||
frame.PayloadLenEx = data.getBigUint64(2);
|
||||
maskingKeyOffset = 10; // 10 byte offset, because we also read 8 bytes with getBigUint64 above (2 bytes (normal size) + 8 bytes)
|
||||
} else {
|
||||
frame.PayloadLenEx = frame.PayloadLen;
|
||||
}
|
||||
|
||||
const maskingKeyEnd = maskingKeyOffset + 4; // (4 bytes because it is a 32 bit value)
|
||||
if (frame.MASK) frame.MaskingKey = data.buffer.slice(maskingKeyOffset, maskingKeyEnd); // Create a new buffer starting at the masking key offset and ending at the masking key end (duh).
|
||||
|
||||
// TODO: Separate extension data from application data
|
||||
frame.PayloadData = data.buffer.slice(maskingKeyEnd, maskingKeyEnd + frame.PayloadLen); // Create a new buffer that starts at the end of the masking key and ends at (the end of the masking key + payload length)
|
||||
frame.PayloadData = data.buffer.slice(maskingKeyEnd, maskingKeyEnd + frame.PayloadLenEx); // Create a new buffer that starts at the end of the masking key and ends at (the end of the masking key + payload length)
|
||||
|
||||
// TODO: implement unmasked string decoding
|
||||
if (frame.MASK) {
|
||||
|
|
|
@ -16,6 +16,27 @@ class Socket {
|
|||
}
|
||||
}
|
||||
|
||||
Socket.prototype.sendText = function(text) {
|
||||
const frame = new parser.WebsocketFrame();
|
||||
frame.FIN = 1;
|
||||
frame.RSVx = 0;
|
||||
frame.Opcode = 0x01;
|
||||
|
||||
frame.MASK = 0;
|
||||
const length = text.length;
|
||||
if (length > 125) {
|
||||
frame.PayloadLen = 126;
|
||||
} else if (length >= 65536) {
|
||||
frame.PayloadLen = 127;
|
||||
} else if (length <= 125) {
|
||||
frame.PayloadLen = length;
|
||||
}
|
||||
frame.PayloadLenEx = length;
|
||||
frame.PayloadData = Buffer.from(text);
|
||||
|
||||
this._socket.write(frame.toBuffer());
|
||||
};
|
||||
|
||||
Socket.prototype._decodePayload = function(payload) {
|
||||
console.log(parser.parseWebsocketFrame(new DataView(payload)));
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue