Skip to content

Commit 35d45c2

Browse files
committed
[perf] Skip masking and unmasking if the masking key is zero
1 parent eb2e3a8 commit 35d45c2

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

lib/receiver.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,13 @@ class Receiver extends Writable {
417417
}
418418

419419
data = this.consume(this._payloadLength);
420-
if (this._masked) unmask(data, this._mask);
420+
421+
if (
422+
this._masked &&
423+
(this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0
424+
) {
425+
unmask(data, this._mask);
426+
}
421427
}
422428

423429
if (this._opcode > 0x07) return this.controlMessage(data);

lib/sender.js

+22-10
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,26 @@ class Sender {
6565
* @public
6666
*/
6767
static frame(data, options) {
68-
const merge = options.mask && options.readOnly;
69-
let offset = options.mask ? 6 : 2;
68+
let mask;
69+
let merge = false;
70+
let offset = 2;
71+
let skipMasking = false;
72+
73+
if (options.mask) {
74+
mask = options.maskBuffer || maskBuffer;
75+
76+
if (options.generateMask) {
77+
options.generateMask(mask);
78+
} else {
79+
randomFillSync(mask, 0, 4);
80+
}
81+
82+
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
83+
if (options.readOnly && !skipMasking) merge = true;
84+
85+
offset = 6;
86+
}
87+
7088
let payloadLength = data.length;
7189

7290
if (data.length >= 65536) {
@@ -93,20 +111,14 @@ class Sender {
93111

94112
if (!options.mask) return [target, data];
95113

96-
const mask = options.maskBuffer ? options.maskBuffer : maskBuffer;
97-
98-
if (options.generateMask) {
99-
options.generateMask(mask);
100-
} else {
101-
randomFillSync(mask, 0, 4);
102-
}
103-
104114
target[1] |= 0x80;
105115
target[offset - 4] = mask[0];
106116
target[offset - 3] = mask[1];
107117
target[offset - 2] = mask[2];
108118
target[offset - 1] = mask[3];
109119

120+
if (skipMasking) return [target, data];
121+
110122
if (merge) {
111123
applyMask(data, mask, target, offset, data.length);
112124
return [target];

test/websocket.test.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,14 @@ describe('WebSocket', () => {
128128
});
129129

130130
it('honors the `generateMask` option', (done) => {
131+
const data = Buffer.from('foo');
131132
const wss = new WebSocket.Server({ port: 0 }, () => {
132133
const ws = new WebSocket(`ws://localhost:${wss.address().port}`, {
133134
generateMask() {}
134135
});
135136

136137
ws.on('open', () => {
137-
ws.send('foo');
138+
ws.send(data);
138139
});
139140

140141
ws.on('close', (code, reason) => {
@@ -152,9 +153,11 @@ describe('WebSocket', () => {
152153
chunks.push(chunk);
153154
});
154155

155-
ws.on('message', () => {
156-
assert.ok(
157-
Buffer.concat(chunks).slice(2, 6).equals(Buffer.alloc(4))
156+
ws.on('message', (message) => {
157+
assert.deepStrictEqual(message, data);
158+
assert.deepStrictEqual(
159+
Buffer.concat(chunks).slice(2, 6),
160+
Buffer.alloc(4)
158161
);
159162

160163
ws.close();

0 commit comments

Comments
 (0)