1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6const assert = require('assert'); 7const http2 = require('http2'); 8 9const check = Buffer.from([0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 10 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 11 0x00, 0x05, 0x00, 0x00, 0x40, 0x00, 12 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, 13 0x00, 0x06, 0x00, 0x00, 0xff, 0xff, 14 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 15 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); 16const val = http2.getPackedSettings(http2.getDefaultSettings()); 17assert.deepStrictEqual(val, check); 18 19[ 20 ['headerTableSize', 0], 21 ['headerTableSize', 2 ** 32 - 1], 22 ['initialWindowSize', 0], 23 ['initialWindowSize', 2 ** 32 - 1], 24 ['maxFrameSize', 16384], 25 ['maxFrameSize', 2 ** 24 - 1], 26 ['maxConcurrentStreams', 0], 27 ['maxConcurrentStreams', 2 ** 31 - 1], 28 ['maxHeaderListSize', 0], 29 ['maxHeaderListSize', 2 ** 32 - 1], 30 ['maxHeaderSize', 0], 31 ['maxHeaderSize', 2 ** 32 - 1] 32].forEach((i) => { 33 // Valid options should not throw. 34 http2.getPackedSettings({ [i[0]]: i[1] }); 35}); 36 37http2.getPackedSettings({ enablePush: true }); 38http2.getPackedSettings({ enablePush: false }); 39 40[ 41 ['headerTableSize', -1], 42 ['headerTableSize', 2 ** 32], 43 ['initialWindowSize', -1], 44 ['initialWindowSize', 2 ** 32], 45 ['maxFrameSize', 16383], 46 ['maxFrameSize', 2 ** 24], 47 ['maxConcurrentStreams', -1], 48 ['maxConcurrentStreams', 2 ** 32], 49 ['maxHeaderListSize', -1], 50 ['maxHeaderListSize', 2 ** 32], 51 ['maxHeaderSize', -1], 52 ['maxHeaderSize', 2 ** 32] 53].forEach((i) => { 54 assert.throws(() => { 55 http2.getPackedSettings({ [i[0]]: i[1] }); 56 }, { 57 code: 'ERR_HTTP2_INVALID_SETTING_VALUE', 58 name: 'RangeError', 59 message: `Invalid value for setting "${i[0]}": ${i[1]}` 60 }); 61}); 62 63[ 64 1, null, '', Infinity, new Date(), {}, NaN, [false] 65].forEach((i) => { 66 assert.throws(() => { 67 http2.getPackedSettings({ enablePush: i }); 68 }, { 69 code: 'ERR_HTTP2_INVALID_SETTING_VALUE', 70 name: 'TypeError', 71 message: `Invalid value for setting "enablePush": ${i}` 72 }); 73}); 74 75[ 76 1, null, '', Infinity, new Date(), {}, NaN, [false] 77].forEach((i) => { 78 assert.throws(() => { 79 http2.getPackedSettings({ enableConnectProtocol: i }); 80 }, { 81 code: 'ERR_HTTP2_INVALID_SETTING_VALUE', 82 name: 'TypeError', 83 message: `Invalid value for setting "enableConnectProtocol": ${i}` 84 }); 85}); 86 87{ 88 const check = Buffer.from([ 89 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 90 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, 91 0x00, 0x05, 0x00, 0x00, 0x4e, 0x20, 92 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 93 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 94 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 95 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); 96 97 const packed = http2.getPackedSettings({ 98 headerTableSize: 100, 99 initialWindowSize: 100, 100 maxFrameSize: 20000, 101 maxConcurrentStreams: 200, 102 maxHeaderListSize: 100, 103 maxHeaderSize: 100, 104 enablePush: true, 105 enableConnectProtocol: false, 106 foo: 'ignored' 107 }); 108 assert.strictEqual(packed.length, 42); 109 assert.deepStrictEqual(packed, check); 110} 111 112// Check for not passing settings. 113{ 114 const packed = http2.getPackedSettings(); 115 assert.strictEqual(packed.length, 0); 116} 117 118{ 119 const packed = Buffer.from([ 120 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 121 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, 122 0x00, 0x05, 0x00, 0x00, 0x4e, 0x20, 123 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 124 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 125 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 126 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); 127 128 [1, true, '', [], {}, NaN].forEach((input) => { 129 assert.throws(() => { 130 http2.getUnpackedSettings(input); 131 }, { 132 code: 'ERR_INVALID_ARG_TYPE', 133 name: 'TypeError', 134 message: 135 'The "buf" argument must be an instance of Buffer, TypedArray, or ' + 136 `DataView.${common.invalidArgTypeHelper(input)}` 137 }); 138 }); 139 140 assert.throws(() => { 141 http2.getUnpackedSettings(packed.slice(5)); 142 }, { 143 code: 'ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH', 144 name: 'RangeError', 145 message: 'Packed settings length must be a multiple of six' 146 }); 147 148 const settings = http2.getUnpackedSettings(packed); 149 150 assert(settings); 151 assert.strictEqual(settings.headerTableSize, 100); 152 assert.strictEqual(settings.initialWindowSize, 100); 153 assert.strictEqual(settings.maxFrameSize, 20000); 154 assert.strictEqual(settings.maxConcurrentStreams, 200); 155 assert.strictEqual(settings.maxHeaderListSize, 100); 156 assert.strictEqual(settings.maxHeaderSize, 100); 157 assert.strictEqual(settings.enablePush, true); 158 assert.strictEqual(settings.enableConnectProtocol, false); 159} 160 161{ 162 const packed = Buffer.from([ 163 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); 165 166 const settings = http2.getUnpackedSettings(packed, { validate: true }); 167 assert.strictEqual(settings.enablePush, false); 168 assert.strictEqual(settings.enableConnectProtocol, false); 169} 170{ 171 const packed = Buffer.from([ 172 0x00, 0x02, 0x00, 0x00, 0x00, 0x64, 173 0x00, 0x08, 0x00, 0x00, 0x00, 0x64]); 174 175 const settings = http2.getUnpackedSettings(packed, { validate: true }); 176 assert.strictEqual(settings.enablePush, true); 177 assert.strictEqual(settings.enableConnectProtocol, true); 178} 179 180// Verify that passing {validate: true} does not throw. 181{ 182 const packed = Buffer.from([ 183 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 184 0x00, 0x03, 0x00, 0x00, 0x00, 0xc8, 185 0x00, 0x05, 0x00, 0x00, 0x4e, 0x20, 186 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 187 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 188 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 189 0x00, 0x08, 0x00, 0x00, 0x00, 0x00]); 190 191 http2.getUnpackedSettings(packed, { validate: true }); 192} 193 194// Check for maxFrameSize failing the max number. 195{ 196 const packed = Buffer.from([0x00, 0x05, 0x01, 0x00, 0x00, 0x00]); 197 198 assert.throws(() => { 199 http2.getUnpackedSettings(packed, { validate: true }); 200 }, { 201 code: 'ERR_HTTP2_INVALID_SETTING_VALUE', 202 name: 'RangeError', 203 message: 'Invalid value for setting "maxFrameSize": 16777216' 204 }); 205} 206