Skip to content

Commit

Permalink
http2: add support for TypedArray to getUnpackedSettings
Browse files Browse the repository at this point in the history
PR-URL: #36141
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
  • Loading branch information
aduh95 authored and codebytere committed Nov 22, 2020
1 parent 3691ecc commit f0aed8c
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
2 changes: 1 addition & 1 deletion doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -2544,7 +2544,7 @@ console.log(packed.toString('base64'));
added: v8.4.0
-->

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

Returns a [HTTP/2 Settings Object][] containing the deserialized settings from
Expand Down
2 changes: 2 additions & 0 deletions lib/internal/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1067,5 +1067,7 @@ module.exports = {
addBufferPrototypeMethods,
markAsUntransferable,
createUnsafeBuffer,
readUInt16BE,
readUInt32BE,
reconnectZeroFillToggle
};
10 changes: 6 additions & 4 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const {
ObjectDefineProperty,
ObjectPrototypeHasOwnProperty,
Promise,
ReflectApply,
ReflectGetPrototypeOf,
Set,
Symbol,
Expand All @@ -32,6 +33,7 @@ const assert = require('assert');
const EventEmitter = require('events');
const fs = require('fs');
const http = require('http');
const { readUInt16BE, readUInt32BE } = require('internal/buffer');
const net = require('net');
const { Duplex } = require('stream');
const tls = require('tls');
Expand Down Expand Up @@ -3208,18 +3210,18 @@ function getPackedSettings(settings) {
}

function getUnpackedSettings(buf, options = {}) {
if (!isArrayBufferView(buf)) {
if (!isArrayBufferView(buf) || buf.length === undefined) {
throw new ERR_INVALID_ARG_TYPE('buf',
['Buffer', 'TypedArray', 'DataView'], buf);
['Buffer', 'TypedArray'], buf);
}
if (buf.length % 6 !== 0)
throw new ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH();
const settings = {};
let offset = 0;
while (offset < buf.length) {
const id = buf.readUInt16BE(offset);
const id = ReflectApply(readUInt16BE, buf, [offset]);
offset += 2;
const value = buf.readUInt32BE(offset);
const value = ReflectApply(readUInt32BE, buf, [offset]);
switch (id) {
case NGHTTP2_SETTINGS_HEADER_TABLE_SIZE:
settings.headerTableSize = value;
Expand Down
56 changes: 54 additions & 2 deletions test/parallel/test-http2-getpackedsettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ http2.getPackedSettings({ enablePush: false });
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
message:
'The "buf" argument must be an instance of Buffer, TypedArray, or ' +
`DataView.${common.invalidArgTypeHelper(input)}`
'The "buf" argument must be an instance of Buffer or TypedArray.' +
common.invalidArgTypeHelper(input)
});
});

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

{
const packed = new Uint16Array([
0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);

assert.throws(() => {
http2.getUnpackedSettings(packed.slice(5));
}, {
code: 'ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
name: 'RangeError',
message: 'Packed settings length must be a multiple of six'
});

const settings = http2.getUnpackedSettings(packed);

assert(settings);
assert.strictEqual(settings.headerTableSize, 100);
assert.strictEqual(settings.initialWindowSize, 100);
assert.strictEqual(settings.maxFrameSize, 20000);
assert.strictEqual(settings.maxConcurrentStreams, 200);
assert.strictEqual(settings.maxHeaderListSize, 100);
assert.strictEqual(settings.maxHeaderSize, 100);
assert.strictEqual(settings.enablePush, true);
assert.strictEqual(settings.enableConnectProtocol, false);
}

{
const packed = new DataView(Buffer.from([
0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00]).buffer);

assert.throws(() => {
http2.getUnpackedSettings(packed);
}, {
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
message:
'The "buf" argument must be an instance of Buffer or TypedArray.' +
common.invalidArgTypeHelper(packed)
});
}

{
const packed = Buffer.from([
0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
Expand Down

0 comments on commit f0aed8c

Please sign in to comment.