Only decompress Websocket frames that have the RSV1 bit set

This commit is contained in:
Alex Dima 2021-09-23 17:17:36 +02:00
parent 94ffa6fc39
commit 636328c20c
No known key found for this signature in database
GPG key ID: 39563C1504FDD0C9

View file

@ -181,6 +181,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
state: ReadState.PeekHeader,
readLen: Constants.MinHeaderByteSize,
fin: 0,
rsv1Bit: 0,
mask: 0
};
@ -396,6 +397,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
const peekHeader = this._incomingData.peek(this._state.readLen);
const firstByte = peekHeader.readUInt8(0);
const finBit = (firstByte & 0b10000000) >>> 7;
const rsv1Bit = (firstByte & 0b01000000) >>> 6;
const secondByte = peekHeader.readUInt8(1);
const hasMask = (secondByte & 0b10000000) >>> 7;
const len = (secondByte & 0b01111111);
@ -403,6 +405,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
this._state.state = ReadState.ReadHeader;
this._state.readLen = Constants.MinHeaderByteSize + (hasMask ? 4 : 0) + (len === 126 ? 2 : 0) + (len === 127 ? 8 : 0);
this._state.fin = finBit;
this._state.rsv1Bit = rsv1Bit;
this._state.mask = 0;
} else if (this._state.state === ReadState.ReadHeader) {
@ -455,7 +458,12 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
this._state.readLen = Constants.MinHeaderByteSize;
this._state.mask = 0;
if (this._zlibInflate) {
if (this._zlibInflate && this._state.rsv1Bit) {
// See https://datatracker.ietf.org/doc/html/rfc7692#section-9.2
// Even if permessageDeflate is negotiated, it is possible
// that the other side might decide to send uncompressed frames
// So only decompress frames that have the RSV 1 bit set
//
// See https://tools.ietf.org/html/rfc7692#section-7.2.2
if (this._recordInflateBytes) {
this._recordedInflateBytes.push(Buffer.from(<Buffer>body.buffer));