11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst http2 = require('http2');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst check = Buffer.from([0x00, 0x01, 0x00, 0x00, 0x10, 0x00,
101cb0ef41Sopenharmony_ci                           0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
111cb0ef41Sopenharmony_ci                           0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
121cb0ef41Sopenharmony_ci                           0x00, 0x04, 0x00, 0x00, 0xff, 0xff,
131cb0ef41Sopenharmony_ci                           0x00, 0x05, 0x00, 0x00, 0x40, 0x00,
141cb0ef41Sopenharmony_ci                           0x00, 0x06, 0x00, 0x00, 0xff, 0xff,
151cb0ef41Sopenharmony_ci                           0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
161cb0ef41Sopenharmony_ciconst val = http2.getPackedSettings(http2.getDefaultSettings());
171cb0ef41Sopenharmony_ciassert.deepStrictEqual(val, check);
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci[
201cb0ef41Sopenharmony_ci  ['headerTableSize', 0],
211cb0ef41Sopenharmony_ci  ['headerTableSize', 2 ** 32 - 1],
221cb0ef41Sopenharmony_ci  ['initialWindowSize', 0],
231cb0ef41Sopenharmony_ci  ['initialWindowSize', 2 ** 32 - 1],
241cb0ef41Sopenharmony_ci  ['maxFrameSize', 16384],
251cb0ef41Sopenharmony_ci  ['maxFrameSize', 2 ** 24 - 1],
261cb0ef41Sopenharmony_ci  ['maxConcurrentStreams', 0],
271cb0ef41Sopenharmony_ci  ['maxConcurrentStreams', 2 ** 31 - 1],
281cb0ef41Sopenharmony_ci  ['maxHeaderListSize', 0],
291cb0ef41Sopenharmony_ci  ['maxHeaderListSize', 2 ** 32 - 1],
301cb0ef41Sopenharmony_ci  ['maxHeaderSize', 0],
311cb0ef41Sopenharmony_ci  ['maxHeaderSize', 2 ** 32 - 1],
321cb0ef41Sopenharmony_ci].forEach((i) => {
331cb0ef41Sopenharmony_ci  // Valid options should not throw.
341cb0ef41Sopenharmony_ci  http2.getPackedSettings({ [i[0]]: i[1] });
351cb0ef41Sopenharmony_ci});
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cihttp2.getPackedSettings({ enablePush: true });
381cb0ef41Sopenharmony_cihttp2.getPackedSettings({ enablePush: false });
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci[
411cb0ef41Sopenharmony_ci  ['headerTableSize', -1],
421cb0ef41Sopenharmony_ci  ['headerTableSize', 2 ** 32],
431cb0ef41Sopenharmony_ci  ['initialWindowSize', -1],
441cb0ef41Sopenharmony_ci  ['initialWindowSize', 2 ** 32],
451cb0ef41Sopenharmony_ci  ['maxFrameSize', 16383],
461cb0ef41Sopenharmony_ci  ['maxFrameSize', 2 ** 24],
471cb0ef41Sopenharmony_ci  ['maxConcurrentStreams', -1],
481cb0ef41Sopenharmony_ci  ['maxConcurrentStreams', 2 ** 32],
491cb0ef41Sopenharmony_ci  ['maxHeaderListSize', -1],
501cb0ef41Sopenharmony_ci  ['maxHeaderListSize', 2 ** 32],
511cb0ef41Sopenharmony_ci  ['maxHeaderSize', -1],
521cb0ef41Sopenharmony_ci  ['maxHeaderSize', 2 ** 32],
531cb0ef41Sopenharmony_ci].forEach((i) => {
541cb0ef41Sopenharmony_ci  assert.throws(() => {
551cb0ef41Sopenharmony_ci    http2.getPackedSettings({ [i[0]]: i[1] });
561cb0ef41Sopenharmony_ci  }, {
571cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
581cb0ef41Sopenharmony_ci    name: 'RangeError',
591cb0ef41Sopenharmony_ci    message: `Invalid value for setting "${i[0]}": ${i[1]}`
601cb0ef41Sopenharmony_ci  });
611cb0ef41Sopenharmony_ci});
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci[
641cb0ef41Sopenharmony_ci  1, null, '', Infinity, new Date(), {}, NaN, [false],
651cb0ef41Sopenharmony_ci].forEach((i) => {
661cb0ef41Sopenharmony_ci  assert.throws(() => {
671cb0ef41Sopenharmony_ci    http2.getPackedSettings({ enablePush: i });
681cb0ef41Sopenharmony_ci  }, {
691cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
701cb0ef41Sopenharmony_ci    name: 'TypeError',
711cb0ef41Sopenharmony_ci    message: `Invalid value for setting "enablePush": ${i}`
721cb0ef41Sopenharmony_ci  });
731cb0ef41Sopenharmony_ci});
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci[
761cb0ef41Sopenharmony_ci  1, null, '', Infinity, new Date(), {}, NaN, [false],
771cb0ef41Sopenharmony_ci].forEach((i) => {
781cb0ef41Sopenharmony_ci  assert.throws(() => {
791cb0ef41Sopenharmony_ci    http2.getPackedSettings({ enableConnectProtocol: i });
801cb0ef41Sopenharmony_ci  }, {
811cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
821cb0ef41Sopenharmony_ci    name: 'TypeError',
831cb0ef41Sopenharmony_ci    message: `Invalid value for setting "enableConnectProtocol": ${i}`
841cb0ef41Sopenharmony_ci  });
851cb0ef41Sopenharmony_ci});
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci{
881cb0ef41Sopenharmony_ci  const check = Buffer.from([
891cb0ef41Sopenharmony_ci    0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
901cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
911cb0ef41Sopenharmony_ci    0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
921cb0ef41Sopenharmony_ci    0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
931cb0ef41Sopenharmony_ci    0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
941cb0ef41Sopenharmony_ci    0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
951cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
961cb0ef41Sopenharmony_ci  ]);
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  const packed = http2.getPackedSettings({
991cb0ef41Sopenharmony_ci    headerTableSize: 100,
1001cb0ef41Sopenharmony_ci    initialWindowSize: 100,
1011cb0ef41Sopenharmony_ci    maxFrameSize: 20000,
1021cb0ef41Sopenharmony_ci    maxConcurrentStreams: 200,
1031cb0ef41Sopenharmony_ci    maxHeaderListSize: 100,
1041cb0ef41Sopenharmony_ci    maxHeaderSize: 100,
1051cb0ef41Sopenharmony_ci    enablePush: true,
1061cb0ef41Sopenharmony_ci    enableConnectProtocol: false,
1071cb0ef41Sopenharmony_ci    foo: 'ignored'
1081cb0ef41Sopenharmony_ci  });
1091cb0ef41Sopenharmony_ci  assert.strictEqual(packed.length, 42);
1101cb0ef41Sopenharmony_ci  assert.deepStrictEqual(packed, check);
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci// Check for not passing settings.
1141cb0ef41Sopenharmony_ci{
1151cb0ef41Sopenharmony_ci  const packed = http2.getPackedSettings();
1161cb0ef41Sopenharmony_ci  assert.strictEqual(packed.length, 0);
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci{
1201cb0ef41Sopenharmony_ci  const packed = Buffer.from([
1211cb0ef41Sopenharmony_ci    0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
1221cb0ef41Sopenharmony_ci    0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
1231cb0ef41Sopenharmony_ci    0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
1241cb0ef41Sopenharmony_ci    0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
1251cb0ef41Sopenharmony_ci    0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
1261cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
1271cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  [1, true, '', [], {}, NaN].forEach((input) => {
1301cb0ef41Sopenharmony_ci    assert.throws(() => {
1311cb0ef41Sopenharmony_ci      http2.getUnpackedSettings(input);
1321cb0ef41Sopenharmony_ci    }, {
1331cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
1341cb0ef41Sopenharmony_ci      name: 'TypeError',
1351cb0ef41Sopenharmony_ci      message:
1361cb0ef41Sopenharmony_ci        'The "buf" argument must be an instance of Buffer or TypedArray.' +
1371cb0ef41Sopenharmony_ci        common.invalidArgTypeHelper(input)
1381cb0ef41Sopenharmony_ci    });
1391cb0ef41Sopenharmony_ci  });
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  assert.throws(() => {
1421cb0ef41Sopenharmony_ci    http2.getUnpackedSettings(packed.slice(5));
1431cb0ef41Sopenharmony_ci  }, {
1441cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
1451cb0ef41Sopenharmony_ci    name: 'RangeError',
1461cb0ef41Sopenharmony_ci    message: 'Packed settings length must be a multiple of six'
1471cb0ef41Sopenharmony_ci  });
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  const settings = http2.getUnpackedSettings(packed);
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  assert(settings);
1521cb0ef41Sopenharmony_ci  assert.strictEqual(settings.headerTableSize, 100);
1531cb0ef41Sopenharmony_ci  assert.strictEqual(settings.initialWindowSize, 100);
1541cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxFrameSize, 20000);
1551cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxConcurrentStreams, 200);
1561cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxHeaderListSize, 100);
1571cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxHeaderSize, 100);
1581cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enablePush, true);
1591cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enableConnectProtocol, false);
1601cb0ef41Sopenharmony_ci}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci{
1631cb0ef41Sopenharmony_ci  const packed = new Uint16Array([
1641cb0ef41Sopenharmony_ci    0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
1651cb0ef41Sopenharmony_ci    0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
1661cb0ef41Sopenharmony_ci    0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
1671cb0ef41Sopenharmony_ci    0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
1681cb0ef41Sopenharmony_ci    0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
1691cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
1701cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  assert.throws(() => {
1731cb0ef41Sopenharmony_ci    http2.getUnpackedSettings(packed.slice(5));
1741cb0ef41Sopenharmony_ci  }, {
1751cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH',
1761cb0ef41Sopenharmony_ci    name: 'RangeError',
1771cb0ef41Sopenharmony_ci    message: 'Packed settings length must be a multiple of six'
1781cb0ef41Sopenharmony_ci  });
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  const settings = http2.getUnpackedSettings(packed);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  assert(settings);
1831cb0ef41Sopenharmony_ci  assert.strictEqual(settings.headerTableSize, 100);
1841cb0ef41Sopenharmony_ci  assert.strictEqual(settings.initialWindowSize, 100);
1851cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxFrameSize, 20000);
1861cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxConcurrentStreams, 200);
1871cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxHeaderListSize, 100);
1881cb0ef41Sopenharmony_ci  assert.strictEqual(settings.maxHeaderSize, 100);
1891cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enablePush, true);
1901cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enableConnectProtocol, false);
1911cb0ef41Sopenharmony_ci}
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci{
1941cb0ef41Sopenharmony_ci  const packed = new DataView(Buffer.from([
1951cb0ef41Sopenharmony_ci    0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
1961cb0ef41Sopenharmony_ci    0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
1971cb0ef41Sopenharmony_ci    0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
1981cb0ef41Sopenharmony_ci    0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
1991cb0ef41Sopenharmony_ci    0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
2001cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
2011cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00]).buffer);
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  assert.throws(() => {
2041cb0ef41Sopenharmony_ci    http2.getUnpackedSettings(packed);
2051cb0ef41Sopenharmony_ci  }, {
2061cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
2071cb0ef41Sopenharmony_ci    name: 'TypeError',
2081cb0ef41Sopenharmony_ci    message:
2091cb0ef41Sopenharmony_ci        'The "buf" argument must be an instance of Buffer or TypedArray.' +
2101cb0ef41Sopenharmony_ci        common.invalidArgTypeHelper(packed)
2111cb0ef41Sopenharmony_ci  });
2121cb0ef41Sopenharmony_ci}
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci{
2151cb0ef41Sopenharmony_ci  const packed = Buffer.from([
2161cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
2171cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci  const settings = http2.getUnpackedSettings(packed, { validate: true });
2201cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enablePush, false);
2211cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enableConnectProtocol, false);
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci{
2241cb0ef41Sopenharmony_ci  const packed = Buffer.from([
2251cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x64,
2261cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x64]);
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  const settings = http2.getUnpackedSettings(packed, { validate: true });
2291cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enablePush, true);
2301cb0ef41Sopenharmony_ci  assert.strictEqual(settings.enableConnectProtocol, true);
2311cb0ef41Sopenharmony_ci}
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci// Verify that passing {validate: true} does not throw.
2341cb0ef41Sopenharmony_ci{
2351cb0ef41Sopenharmony_ci  const packed = Buffer.from([
2361cb0ef41Sopenharmony_ci    0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
2371cb0ef41Sopenharmony_ci    0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
2381cb0ef41Sopenharmony_ci    0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
2391cb0ef41Sopenharmony_ci    0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
2401cb0ef41Sopenharmony_ci    0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
2411cb0ef41Sopenharmony_ci    0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
2421cb0ef41Sopenharmony_ci    0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci  http2.getUnpackedSettings(packed, { validate: true });
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci// Check for maxFrameSize failing the max number.
2481cb0ef41Sopenharmony_ci{
2491cb0ef41Sopenharmony_ci  const packed = Buffer.from([0x00, 0x05, 0x01, 0x00, 0x00, 0x00]);
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  assert.throws(() => {
2521cb0ef41Sopenharmony_ci    http2.getUnpackedSettings(packed, { validate: true });
2531cb0ef41Sopenharmony_ci  }, {
2541cb0ef41Sopenharmony_ci    code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
2551cb0ef41Sopenharmony_ci    name: 'RangeError',
2561cb0ef41Sopenharmony_ci    message: 'Invalid value for setting "maxFrameSize": 16777216'
2571cb0ef41Sopenharmony_ci  });
2581cb0ef41Sopenharmony_ci}
259