Skip to content

Commit 74fe1d8

Browse files
aduh95targos
authored andcommitted
http2: add support for TypedArray to getUnpackedSettings
PR-URL: #36141 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent dec3610 commit 74fe1d8

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
@@ -2543,7 +2543,7 @@ console.log(packed.toString('base64'));
25432543
added: v8.4.0
25442544
-->
25452545

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

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

lib/internal/buffer.js

+2
Original file line numberDiff line numberDiff line change
@@ -1043,4 +1043,6 @@ module.exports = {
10431043
FastBuffer,
10441044
addBufferPrototypeMethods,
10451045
markAsUntransferable,
1046+
readUInt16BE,
1047+
readUInt32BE,
10461048
};

lib/internal/http2/core.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
ObjectDefineProperty,
1313
ObjectPrototypeHasOwnProperty,
1414
Promise,
15+
ReflectApply,
1516
ReflectGetPrototypeOf,
1617
Set,
1718
Symbol,
@@ -31,6 +32,7 @@ const assert = require('assert');
3132
const EventEmitter = require('events');
3233
const fs = require('fs');
3334
const http = require('http');
35+
const { readUInt16BE, readUInt32BE } = require('internal/buffer');
3436
const net = require('net');
3537
const { Duplex } = require('stream');
3638
const tls = require('tls');
@@ -3207,18 +3209,18 @@ function getPackedSettings(settings) {
32073209
}
32083210

32093211
function getUnpackedSettings(buf, options = {}) {
3210-
if (!isArrayBufferView(buf)) {
3212+
if (!isArrayBufferView(buf) || buf.length === undefined) {
32113213
throw new ERR_INVALID_ARG_TYPE('buf',
3212-
['Buffer', 'TypedArray', 'DataView'], buf);
3214+
['Buffer', 'TypedArray'], buf);
32133215
}
32143216
if (buf.length % 6 !== 0)
32153217
throw new ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH();
32163218
const settings = {};
32173219
let offset = 0;
32183220
while (offset < buf.length) {
3219-
const id = buf.readUInt16BE(offset);
3221+
const id = ReflectApply(readUInt16BE, buf, [offset]);
32203222
offset += 2;
3221-
const value = buf.readUInt32BE(offset);
3223+
const value = ReflectApply(readUInt32BE, buf, [offset]);
32223224
switch (id) {
32233225
case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
32243226
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)