Skip to content

Commit f0aed8c

Browse files
aduh95codebytere
authored andcommitted
http2: add support for TypedArray to getUnpackedSettings
PR-URL: #36141 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 3691ecc commit f0aed8c

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

doc/api/http2.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,7 @@ console.log(packed.toString('base64'));
25442544
added: v8.4.0
25452545
-->
25462546

2547-
* `buf` {Buffer|Uint8Array} The packed settings.
2547+
* `buf` {Buffer|TypedArray} The packed settings.
25482548
* Returns: {HTTP/2 Settings Object}
25492549

25502550
Returns a [HTTP/2 Settings Object][] containing the deserialized settings from

lib/internal/buffer.js

+2
Original file line numberDiff line numberDiff line change
@@ -1067,5 +1067,7 @@ module.exports = {
10671067
addBufferPrototypeMethods,
10681068
markAsUntransferable,
10691069
createUnsafeBuffer,
1070+
readUInt16BE,
1071+
readUInt32BE,
10701072
reconnectZeroFillToggle
10711073
};

lib/internal/http2/core.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
ObjectDefineProperty,
1414
ObjectPrototypeHasOwnProperty,
1515
Promise,
16+
ReflectApply,
1617
ReflectGetPrototypeOf,
1718
Set,
1819
Symbol,
@@ -32,6 +33,7 @@ const assert = require('assert');
3233
const EventEmitter = require('events');
3334
const fs = require('fs');
3435
const http = require('http');
36+
const { readUInt16BE, readUInt32BE } = require('internal/buffer');
3537
const net = require('net');
3638
const { Duplex } = require('stream');
3739
const tls = require('tls');
@@ -3208,18 +3210,18 @@ function getPackedSettings(settings) {
32083210
}
32093211

32103212
function getUnpackedSettings(buf, options = {}) {
3211-
if (!isArrayBufferView(buf)) {
3213+
if (!isArrayBufferView(buf) || buf.length === undefined) {
32123214
throw new ERR_INVALID_ARG_TYPE('buf',
3213-
['Buffer', 'TypedArray', 'DataView'], buf);
3215+
['Buffer', 'TypedArray'], buf);
32143216
}
32153217
if (buf.length % 6 !== 0)
32163218
throw new ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH();
32173219
const settings = {};
32183220
let offset = 0;
32193221
while (offset < buf.length) {
3220-
const id = buf.readUInt16BE(offset);
3222+
const id = ReflectApply(readUInt16BE, buf, [offset]);
32213223
offset += 2;
3222-
const value = buf.readUInt32BE(offset);
3224+
const value = ReflectApply(readUInt32BE, buf, [offset]);
32233225
switch (id) {
32243226
case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
32253227
settings.headerTableSize = value;

test/parallel/test-http2-getpackedsettings.js

+54-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ http2.getPackedSettings({ enablePush: false });
133133
code: 'ERR_INVALID_ARG_TYPE',
134134
name: 'TypeError',
135135
message:
136-
'The "buf" argument must be an instance of Buffer, TypedArray, or ' +
137-
`DataView.${common.invalidArgTypeHelper(input)}`
136+
'The "buf" argument must be an instance of Buffer or TypedArray.' +
137+
common.invalidArgTypeHelper(input)
138138
});
139139
});
140140

@@ -159,6 +159,58 @@ http2.getPackedSettings({ enablePush: false });
159159
assert.strictEqual(settings.enableConnectProtocol, false);
160160
}
161161

162+
{
163+
const packed = new Uint16Array([
164+
0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
165+
0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
166+
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
167+
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
168+
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
169+
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
170+
0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
171+
172+
assert.throws(() => {
173+
http2.getUnpackedSettings(packed.slice(5));
174+
}, {
175+
code: 'ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
176+
name: 'RangeError',
177+
message: 'Packed settings length must be a multiple of six'
178+
});
179+
180+
const settings = http2.getUnpackedSettings(packed);
181+
182+
assert(settings);
183+
assert.strictEqual(settings.headerTableSize, 100);
184+
assert.strictEqual(settings.initialWindowSize, 100);
185+
assert.strictEqual(settings.maxFrameSize, 20000);
186+
assert.strictEqual(settings.maxConcurrentStreams, 200);
187+
assert.strictEqual(settings.maxHeaderListSize, 100);
188+
assert.strictEqual(settings.maxHeaderSize, 100);
189+
assert.strictEqual(settings.enablePush, true);
190+
assert.strictEqual(settings.enableConnectProtocol, false);
191+
}
192+
193+
{
194+
const packed = new DataView(Buffer.from([
195+
0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
196+
0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
197+
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
198+
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
199+
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
200+
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
201+
0x00, 0x08, 0x00, 0x00, 0x00, 0x00]).buffer);
202+
203+
assert.throws(() => {
204+
http2.getUnpackedSettings(packed);
205+
}, {
206+
code: 'ERR_INVALID_ARG_TYPE',
207+
name: 'TypeError',
208+
message:
209+
'The "buf" argument must be an instance of Buffer or TypedArray.' +
210+
common.invalidArgTypeHelper(packed)
211+
});
212+
}
213+
162214
{
163215
const packed = Buffer.from([
164216
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,

0 commit comments

Comments
 (0)