Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
e54ddf8
src: support configurable snapshot
joyeecheung Oct 28, 2023
efa13e1
doc: add documentation for --build-snapshot-config
addaleax Nov 16, 2023
e2f8d74
deps: update zlib to 1.3.0.1-motley-dd5fc13
nodejs-github-bot Dec 16, 2023
2c227b0
doc: fix simdjson wrong link
marco-ippolito Dec 16, 2023
3f4fd6e
watch: fix infinite loop when passing --watch=true flag
pulkit-30 Dec 16, 2023
e5017a5
crypto: update CryptoKey symbol properties
panva Nov 25, 2023
13a1241
assert,crypto: make KeyObject and CryptoKey testable for equality
panva Nov 24, 2023
63db82a
test_runner: fixed to run after hook if before throws an error
pulkit-30 Dec 17, 2023
89eee77
http2: addtl http/2 settings
martenrichter Dec 18, 2023
1c71435
doc: fix `TestsStream` parent class
Dec 18, 2023
e636d83
doc: correct note on behavior of stats.isDirectory
NReilingh Dec 18, 2023
5b229d7
fs: validate fd synchronously on c++
anonrig Dec 18, 2023
df8927a
doc: mention native addons are restricted in pm
RafaelGSS Dec 19, 2023
c96ef65
tools: update eslint to 8.56.0
nodejs-github-bot Dec 19, 2023
b2135ae
node-api: segregate nogc APIs from rest via type system
gabrielschulhof Dec 19, 2023
a325746
http: do not override user-provided options object
KuthorX Dec 19, 2023
f9d4e07
doc: remove version from `maintaining-dependencies.md`
aduh95 Dec 19, 2023
d0d2faf
tools: update lint-md-dependencies to rollup@4.9.0
nodejs-github-bot Dec 19, 2023
3ecc7dc
deps: update acorn-walk to 8.3.0
nodejs-github-bot Oct 29, 2023
75e5615
deps: update acorn-walk to 8.3.1
nodejs-github-bot Dec 10, 2023
8a2dd93
src: implement FastByteLengthUtf8 with simdutf::utf8_length_from_latin1
lemire Dec 19, 2023
d7c2572
test: fix flakiness in worker*.test-free-called
MrJithil Dec 19, 2023
5453abd
doc: set exit code in custom test runner example
mcollina Dec 20, 2023
7421467
fs: improve mkdtemp performance for buffer prefix
anonrig Dec 20, 2023
6d1bfcb
deps: update googletest to 530d5c8
nodejs-github-bot Dec 20, 2023
a07d6e2
deps: update simdjson to 3.6.3
nodejs-github-bot Dec 10, 2023
3759491
tools: check timezone current version
marco-ippolito Dec 20, 2023
7e9a0b1
test: use tmpdir.refresh() in test-esm-json.mjs
lpinca Dec 20, 2023
8a2178c
test: use tmpdir.refresh() in test-esm-loader-resolve-type.mjs
lpinca Dec 20, 2023
4b19e62
doc: remove ambiguous 'considered'
Trott Dec 20, 2023
e4be5b6
net: add connection attempt events
ShogunPanda Dec 21, 2023
83a99cc
meta: update artifact actions to v4
targos Dec 21, 2023
c13a5c0
doc: mention node:wasi in the Threat Model
RafaelGSS Dec 21, 2023
b6f232e
test: add URL tests to fs-read in pm
RafaelGSS Dec 21, 2023
7e98349
test: replace forEach with for-of in test-v8-serders.js
iannonoss Dec 21, 2023
3310095
repl: fix prepareStackTrace frames array order
legendecas Nov 21, 2023
291265c
lib: expose default prepareStackTrace
legendecas Nov 20, 2023
ec6fcff
doc: fix limitations and known issues in pm
RafaelGSS Dec 21, 2023
8f4325d
permission: fix wildcard when children > 1
RafaelGSS Dec 21, 2023
8ff6bc4
lib,permission: handle buffer on fs.symlink
RafaelGSS Dec 21, 2023
a69c7d7
src,permission: add --allow-addon flag
RafaelGSS Dec 21, 2023
25eba3d
deps: V8: cherry-pick de611e69ad51
kvakil Dec 21, 2023
c7a1359
http: remove misleading warning
lpinca Dec 21, 2023
e24249c
fs: remove `internalModuleReadJSON` binding
anonrig Dec 21, 2023
c87e5d5
fs: add missing jsdoc parameters to `readSync`
anonrig Dec 21, 2023
9bfd84c
test: replace forEach with for of in test-trace-events-api.js
andp97 Nov 18, 2023
b621ada
module: move the CJS exports cache to internal/modules/cjs/loader
joyeecheung Dec 14, 2023
f1cb583
test: replace forEach() with for...of in test/parallel/test-util-log.js
edodusi Nov 18, 2023
38232d1
test: replace forEach with for of in file test-trace-events-net.js
Ianna83 Nov 18, 2023
3db376f
test: skip test-watch-mode-inspect on arm
mhdawson Dec 22, 2023
876743e
doc: run license-builder
github-actions[bot] Dec 22, 2023
88e8651
test: move to for of loop in test-http-hostname-typechecking.js
Puppo Dec 22, 2023
57c6455
test: replace forEach with for-of in test-webcrypto-export-import-ec
cricciardi Dec 22, 2023
3a49205
node-api: type tag external values without v8::Private
legendecas Dec 22, 2023
e5a8fa0
fs: make offset, position & length args in fh.read() optional
pulkit-30 Dec 22, 2023
96d64ed
src: use BignumPointer and use BN_clear_free
jasnell Oct 28, 2023
ed7305e
lib: reduce overhead of `SafePromiseAllSettledReturnVoid` calls
aduh95 Dec 22, 2023
6648a5c
meta: notify tsc on changes in SECURITY.md
RafaelGSS Dec 22, 2023
8f845eb
lib: move function declaration outside of loop
sanjaiyan-dev Dec 23, 2023
efa12a8
deps: update simdutf to 4.0.8
nodejs-github-bot Dec 23, 2023
c31ed51
timers: export timers.promises
marco-ippolito Dec 23, 2023
8ee882a
doc: mark `--jitless` as experimental
aduh95 Dec 23, 2023
6241429
lib: fix use of `--frozen-intrinsics` with `--jitless`
aduh95 Dec 23, 2023
17c73e6
src: fix unix abstract socket path for trace event
theanarkh Dec 23, 2023
941aedc
errors: fix stacktrace of SystemError
Uzlopak Sep 29, 2023
aaf710f
test: replace forEach test-http-server-multiheaders2
mmachera Nov 18, 2023
8412751
doc: improve localWindowSize event descriptions
DavyLandman Dec 6, 2023
47548d9
esm: fix hint on invalid module specifier
aduh95 Dec 23, 2023
979cebc
test_runner: fixed test object is incorrectly passed to setup()
pulkit-30 Dec 24, 2023
917d887
tools: update lint-md-dependencies to rollup@4.9.1
nodejs-github-bot Dec 24, 2023
cd61fce
build: add `-flax-vector-conversions` to V8 build
targos Dec 24, 2023
e443953
stream: fix cloned webstreams not being unref'd
jasnell Dec 24, 2023
df31c81
src: eliminate duplicate code in histogram.cc
jasnell Dec 25, 2023
684dd9d
test: fix inconsistency write size in `test-fs-readfile-tostring-fail`
Dec 25, 2023
f4f781d
util: pass invalidSubtypeIndex instead of trimmedSubtype to error
gaurishhs Dec 25, 2023
864ecb0
src: do not treat all paths ending with node_modules as such
targos Dec 25, 2023
54dd978
src: enter isolate before destructing IsolateData
bnoordhuis Dec 25, 2023
4dcc511
benchmark: remove dependency on unshipped tools
AdamMajer Dec 13, 2023
a41dca0
deps: update zlib to 1.3.0.1-motley-40e35a7
nodejs-github-bot Dec 26, 2023
82de660
stream: fix code style
MattiasBuelens Dec 26, 2023
5b32e21
quic: add quic internalBinding, refine Endpoint, add types
jasnell Dec 9, 2023
e03ac83
build: fix arm64 cross-compilation
targos Dec 27, 2023
f00f120
deps: update brotli to 1.1.0
nodejs-github-bot Dec 27, 2023
29b8157
src: refactor `GetCreationContext` calls
anonrig Dec 28, 2023
652af45
test: replace forEach() with for...of
JJJ54321 Nov 7, 2023
091098f
fs: fix fs.promises.realpath for long paths on Windows
sapphi-red Dec 28, 2023
4a5d3bd
doc: the GN files should use Node's license
zcbenz Dec 28, 2023
56e8969
watch: fix null `fileName` on windows systems
vnc5 Dec 28, 2023
c3126fc
tools: update inspector_protocol to ca525fc
cola119 Dec 27, 2023
ef4f46f
tools: update inspector_protocol to 547c5b8
cola119 Dec 27, 2023
d181684
tools: update inspector_protocol to 912eb68
cola119 Dec 27, 2023
60d8048
tools: update inspector_protocol to d7b099b
cola119 Dec 27, 2023
e325f49
tools: update inspector_protocol to 2f51e05
cola119 Dec 27, 2023
69a46ad
tools: update inspector_protocol to 9b4a4aa
cola119 Dec 27, 2023
bdcb5ed
tools: update inspector_protocol to c488ba2
cola119 Dec 27, 2023
d5a5f12
tools: fix dep_updaters dir updates
targos Dec 29, 2023
e53cbb2
deps: update ngtcp2 and nghttp3
jasnell Dec 26, 2023
7ecf994
quic: update quic impl to use latest ngtcp2/nghttp3
jasnell Dec 26, 2023
115e058
src: add fast api for Histogram
jasnell Dec 29, 2023
ef44f9b
test: replace foreach with for of
lucacapocci94-dev Dec 29, 2023
549e4b4
test: replace forEach with for...of
Nov 18, 2023
85ee2f7
test: replace forEach() with for...of
Nov 10, 2023
e7925e6
src,stream: improve WriteString
ywave620 Dec 30, 2023
416b4f8
lib,src,permission: port path.resolve to C++
RafaelGSS Dec 30, 2023
867b484
watch: clarify that the fileName parameter can be null
lpinca Dec 30, 2023
2eb41f8
build: fix for VScode "Reopen in Container"
ohhmm Dec 31, 2023
24a9a72
deps: update acorn to 8.11.3
nodejs-github-bot Jan 2, 2024
c0d2e8b
deps: update corepack to 0.24.0
nodejs-github-bot Jan 2, 2024
fc10f88
tools: update lint-md-dependencies to rollup@4.9.2
nodejs-github-bot Jan 2, 2024
a0ff00b
src: avoid draining platform tasks at FreeEnvironment
legendecas Jan 8, 2024
757a84c
test: fix flaky conditions for ppc64 SEA tests
richardlau Jan 11, 2024
f38a9a5
2024-01-15, Version 21.6.0 (Current)
RafaelGSS Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
http2: addtl http/2 settings
Currently, node.js http/2 is limited in sending SETTINGs,
that are currently implemented by nghttp2.
However, nghttp2 has the ability to send arbitary SETTINGs,
that are not known beforehand.
This patch adds this feature including a fall back mechanism,
if a SETTING is implemented in a later nghttp2 or node version.

Fixes: #1337
PR-URL: #49025
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
  • Loading branch information
martenrichter authored and RafaelGSS committed Jan 2, 2024
commit 89eee7763fece62952d28eefcbddde7f0d3a6369
6 changes: 6 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1710,6 +1710,12 @@ When setting the priority for an HTTP/2 stream, the stream may be marked as
a dependency for a parent stream. This error code is used when an attempt is
made to mark a stream and dependent of itself.

<a id="ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS"></a>

### `ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS`

The number of supported custom settings (10) has been exceeded.

<a id="ERR_HTTP2_TOO_MANY_INVALID_FRAMES"></a>

### `ERR_HTTP2_TOO_MANY_INVALID_FRAMES`
Expand Down
13 changes: 13 additions & 0 deletions doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -3010,6 +3010,19 @@ properties.
meaningful if sent by the server. Once the `enableConnectProtocol` setting
has been enabled for a given `Http2Session`, it cannot be disabled.
**Default:** `false`.
* `customSettings` {Object} Specifies additional settings, yet not implemented
in node and the underlying libraries. The key of the object defines the
numeric value of the settings type (as defined in the "HTTP/2 SETTINGS"
registry established by \[RFC 7540]) and the values the actual numeric value
of the settings.
The settings type has to be an integer in the range from 1 to 2^16-1.
It should not be a settings type already handled by node, i.e. currently
it should be greater than 6, although it is not an error.
The values need to be unsigned integers in the range from 0 to 2^32-1.
Currently, a maximum of up 10 custom settings is supported.
It is only supported for sending SETTINGS.
Custom settings are not supported for the functions retrieving remote and
local settings as nghttp2 does not pass unknown HTTP/2 settings to Node.js.

All additional properties on the settings object are ignored.

Expand Down
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1279,6 +1279,8 @@ E('ERR_HTTP2_STREAM_CANCEL', function(error) {
E('ERR_HTTP2_STREAM_ERROR', 'Stream closed with error code %s', Error);
E('ERR_HTTP2_STREAM_SELF_DEPENDENCY',
'A stream cannot depend on itself', Error);
E('ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS',
'Number of custom settings exceeds MAX_ADDITIONAL_SETTINGS', Error);
E('ERR_HTTP2_TOO_MANY_INVALID_FRAMES', 'Too many invalid HTTP/2 frames', Error);
E('ERR_HTTP2_TRAILERS_ALREADY_SENT',
'Trailing headers have already been sent', Error);
Expand Down
6 changes: 6 additions & 0 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,8 @@ function pingCallback(cb) {
// All settings are optional and may be left undefined
const validateSettings = hideStackFrames((settings) => {
if (settings === undefined) return;
assertIsObject.withoutStackTrace(settings.customSettings, 'customSettings', 'Number');

assertWithinRange.withoutStackTrace('headerTableSize',
settings.headerTableSize,
0, kMaxInt);
Expand Down Expand Up @@ -3387,6 +3389,10 @@ function getUnpackedSettings(buf, options = kEmptyObject) {
break;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
settings.enableConnectProtocol = value !== 0;
break;
default:
if (!settings.customSettings) settings.customSettings = {};
settings.customSettings[id] = value;
}
offset += 4;
}
Expand Down
79 changes: 79 additions & 0 deletions lib/internal/http2/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
Error,
MathMax,
Number,
NumberIsNaN,
ObjectKeys,
SafeSet,
String,
Expand All @@ -24,6 +25,7 @@ const {
ERR_HTTP2_INVALID_CONNECTION_HEADERS,
ERR_HTTP2_INVALID_PSEUDOHEADER: { HideStackFramesError: ERR_HTTP2_INVALID_PSEUDOHEADER },
ERR_HTTP2_INVALID_SETTING_VALUE,
ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_HTTP_TOKEN,
},
Expand Down Expand Up @@ -190,6 +192,9 @@ const IDX_SETTINGS_MAX_HEADER_LIST_SIZE = 5;
const IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL = 6;
const IDX_SETTINGS_FLAGS = 7;

// Maximum number of allowed additional settings
const MAX_ADDITIONAL_SETTINGS = 10;

const IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE = 0;
const IDX_SESSION_STATE_EFFECTIVE_RECV_DATA_LENGTH = 1;
const IDX_SESSION_STATE_NEXT_STREAM_ID = 2;
Expand Down Expand Up @@ -348,6 +353,80 @@ function getSettings(session, remote) {

function updateSettingsBuffer(settings) {
let flags = 0;
let numCustomSettings = 0;

if (typeof settings.customSettings === 'object') {
const customSettings = settings.customSettings;
for (const setting in customSettings) {
const val = customSettings[setting];
if (typeof val === 'number') {
let set = false;
const nsetting = Number(setting);
if (NumberIsNaN(nsetting) ||
typeof nsetting !== 'number' ||
0 >= nsetting ||
nsetting > 0xffff)
throw new ERR_HTTP2_INVALID_SETTING_VALUE.RangeError(
'Range Error', nsetting, 0, 0xffff);
if (NumberIsNaN(val) ||
typeof val !== 'number' ||
0 >= val ||
val > 0xffffffff)
throw new ERR_HTTP2_INVALID_SETTING_VALUE.RangeError(
'Range Error', val, 0, 0xffffffff);
if (nsetting < IDX_SETTINGS_FLAGS) {
set = true;
switch (nsetting) {
case IDX_SETTINGS_HEADER_TABLE_SIZE:
flags |= (1 << IDX_SETTINGS_HEADER_TABLE_SIZE);
settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
val;
break;
case IDX_SETTINGS_ENABLE_PUSH:
flags |= (1 << IDX_SETTINGS_ENABLE_PUSH);
settingsBuffer[IDX_SETTINGS_ENABLE_PUSH] = val;
break;
case IDX_SETTINGS_INITIAL_WINDOW_SIZE:
flags |= (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE);
settingsBuffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
val;
break;
case IDX_SETTINGS_MAX_FRAME_SIZE:
flags |= (1 << IDX_SETTINGS_MAX_FRAME_SIZE);
settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
val;
break;
case IDX_SETTINGS_MAX_CONCURRENT_STREAMS:
flags |= (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS);
settingsBuffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] = val;
break;
case IDX_SETTINGS_MAX_HEADER_LIST_SIZE:
flags |= (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE);
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
val;
break;
case IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL:
flags |= (1 << IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL);
settingsBuffer[IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL] = val;
break;
default:
set = false;
break;
}
}
if (!set) { // not supported
if (numCustomSettings === MAX_ADDITIONAL_SETTINGS)
throw new ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS();

settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 1] = nsetting;
settingsBuffer[IDX_SETTINGS_FLAGS + 1 + 2 * numCustomSettings + 2] = val;
numCustomSettings++;
}
}
}
}
settingsBuffer[IDX_SETTINGS_FLAGS + 1] = numCustomSettings;

if (typeof settings.headerTableSize === 'number') {
flags |= (1 << IDX_SETTINGS_HEADER_TABLE_SIZE);
settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
Expand Down
15 changes: 14 additions & 1 deletion src/node_http2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,16 @@ size_t Http2Settings::Init(
HTTP2_SETTINGS(V)
#undef V

uint32_t numAddSettings = buffer[IDX_SETTINGS_COUNT + 1];
if (numAddSettings > 0) {
uint32_t offset = IDX_SETTINGS_COUNT + 1 + 1;
for (uint32_t i = 0; i < numAddSettings; i++) {
uint32_t key = buffer[offset + i * 2 + 0];
uint32_t val = buffer[offset + i * 2 + 1];
entries[count++] = nghttp2_settings_entry{(int32_t)key, val};
}
}

return count;
}
#undef GRABSETTING
Expand Down Expand Up @@ -262,7 +272,7 @@ Local<Value> Http2Settings::Pack() {
}

Local<Value> Http2Settings::Pack(Http2State* state) {
nghttp2_settings_entry entries[IDX_SETTINGS_COUNT];
nghttp2_settings_entry entries[IDX_SETTINGS_COUNT + MAX_ADDITIONAL_SETTINGS];
size_t count = Init(state, entries);
return Pack(state->env(), count, entries);
}
Expand Down Expand Up @@ -298,6 +308,8 @@ void Http2Settings::Update(Http2Session* session, get_setting fn) {
fn(session->session(), NGHTTP2_SETTINGS_ ## name);
HTTP2_SETTINGS(V)
#undef V
buffer[IDX_SETTINGS_COUNT + 1] =
0; // no additional settings are coming, clear them
}

// Initializes the shared TypedArray with the default settings values.
Expand All @@ -314,6 +326,7 @@ void Http2Settings::RefreshDefaults(Http2State* http2_state) {
#undef V

buffer[IDX_SETTINGS_COUNT] = flags;
buffer[IDX_SETTINGS_COUNT + 1] = 0; // no additional settings
}


Expand Down
2 changes: 1 addition & 1 deletion src/node_http2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ class Http2Settings : public AsyncWrap {
v8::Global<v8::Function> callback_;
uint64_t startTime_;
size_t count_ = 0;
nghttp2_settings_entry entries_[IDX_SETTINGS_COUNT];
nghttp2_settings_entry entries_[IDX_SETTINGS_COUNT + MAX_ADDITIONAL_SETTINGS];
};

class Origins {
Expand Down
19 changes: 14 additions & 5 deletions src/node_http2_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ namespace http2 {
IDX_SETTINGS_COUNT
};

// number of max additional settings, thus settings not implemented by nghttp2
const size_t MAX_ADDITIONAL_SETTINGS = 10;

enum Http2SessionStateIndex {
IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE,
IDX_SESSION_STATE_EFFECTIVE_RECV_DATA_LENGTH,
Expand Down Expand Up @@ -108,10 +111,11 @@ class Http2State : public BaseObject {
offsetof(http2_state_internal, options_buffer),
IDX_OPTIONS_FLAGS + 1,
root_buffer),
settings_buffer(realm->isolate(),
offsetof(http2_state_internal, settings_buffer),
IDX_SETTINGS_COUNT + 1,
root_buffer) {}
settings_buffer(
realm->isolate(),
offsetof(http2_state_internal, settings_buffer),
IDX_SETTINGS_COUNT + 1 + 1 + 2 * MAX_ADDITIONAL_SETTINGS,
root_buffer) {}

AliasedUint8Array root_buffer;
AliasedFloat64Array session_state_buffer;
Expand All @@ -135,7 +139,12 @@ class Http2State : public BaseObject {
double stream_stats_buffer[IDX_STREAM_STATS_COUNT];
double session_stats_buffer[IDX_SESSION_STATS_COUNT];
uint32_t options_buffer[IDX_OPTIONS_FLAGS + 1];
uint32_t settings_buffer[IDX_SETTINGS_COUNT + 1];
// first + 1: number of actual nghttp2 supported settings
// second + 1: number of additional settings not suppoted by nghttp2
// 2 * MAX_ADDITIONAL_SETTINGS: settings id and value for each
// additional setting
uint32_t settings_buffer[IDX_SETTINGS_COUNT + 1 + 1 +
2 * MAX_ADDITIONAL_SETTINGS];
};
};

Expand Down
88 changes: 85 additions & 3 deletions test/parallel/test-http2-getpackedsettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ assert.deepStrictEqual(val, check);
['maxHeaderListSize', 2 ** 32 - 1],
['maxHeaderSize', 0],
['maxHeaderSize', 2 ** 32 - 1],
['customSettings', { '9999': 301 }],
].forEach((i) => {
// Valid options should not throw.
http2.getPackedSettings({ [i[0]]: i[1] });
Expand Down Expand Up @@ -93,6 +94,7 @@ http2.getPackedSettings({ enablePush: false });
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x27, 0x0F, 0x00, 0x00, 0x01, 0x2d,
]);

const packed = http2.getPackedSettings({
Expand All @@ -104,12 +106,90 @@ http2.getPackedSettings({ enablePush: false });
maxHeaderSize: 100,
enablePush: true,
enableConnectProtocol: false,
foo: 'ignored'
foo: 'ignored',
customSettings: { '9999': 301 }
});
assert.strictEqual(packed.length, 42);
assert.strictEqual(packed.length, 48);
assert.deepStrictEqual(packed, check);
}

// Check if multiple custom settings can be set
{
const check = Buffer.from([
0x00, 0x01, 0x00, 0x00, 0x00, 0x64,
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
0x00, 0x03, 0x00, 0x00, 0x00, 0xc8,
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
0x00, 0x05, 0x00, 0x00, 0x4e, 0x20,
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x03, 0xf3, 0x00, 0x00, 0x07, 0x9F,
0x0a, 0x2e, 0x00, 0x00, 0x00, 0x58,
]);

const packed = http2.getPackedSettings({
headerTableSize: 100,
initialWindowSize: 100,
maxFrameSize: 20000,
maxConcurrentStreams: 200,
maxHeaderListSize: 100,
maxHeaderSize: 100,
enablePush: true,
enableConnectProtocol: false,
customSettings: { '2606': 88, '1011': 1951 }
});
assert.strictEqual(packed.length, 54);
assert.deepStrictEqual(packed, check);
}

{
// Check if wrong custom settings cause an error

assert.throws(() => {
http2.getPackedSettings({
customSettings: { '-1': 659685 }
});
}, {
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
name: 'RangeError'
});

assert.throws(() => {
http2.getPackedSettings({
customSettings: { '10': 34577577777 }
});
}, {
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
name: 'RangeError'
});

assert.throws(() => {
http2.getPackedSettings({
customSettings: { 'notvalid': -777 }
});
}, {
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
name: 'RangeError'
});

assert.throws(() => {
http2.getPackedSettings({
customSettings: { '11': 11, '12': 12, '13': 13, '14': 14, '15': 15, '16': 16,
'17': 17, '18': 18, '19': 19, '20': 20, '21': 21 }
});
}, {
code: 'ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS'
});
assert.throws(() => {
http2.getPackedSettings({
customSettings: { '11': 11, '12': 12, '13': 13, '14': 14, '15': 15, '16': 16,
'17': 17, '18': 18, '19': 19, '20': 20, '21': 21, '22': 22 }
});
}, {
code: 'ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS'
});
}

// Check for not passing settings.
{
const packed = http2.getPackedSettings();
Expand All @@ -124,7 +204,8 @@ http2.getPackedSettings({ enablePush: false });
0x00, 0x04, 0x00, 0x00, 0x00, 0x64,
0x00, 0x06, 0x00, 0x00, 0x00, 0x64,
0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00]);
0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x27, 0x0F, 0x00, 0x00, 0x01, 0x2d]);

[1, true, '', [], {}, NaN].forEach((input) => {
assert.throws(() => {
Expand Down Expand Up @@ -157,6 +238,7 @@ http2.getPackedSettings({ enablePush: false });
assert.strictEqual(settings.maxHeaderSize, 100);
assert.strictEqual(settings.enablePush, true);
assert.strictEqual(settings.enableConnectProtocol, false);
assert.deepStrictEqual(settings.customSettings, { '9999': 301 });
}

{
Expand Down
3 changes: 2 additions & 1 deletion test/parallel/test-http2-update-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ testUpdateSettingsWith({
'maxHeaderListSize': 1,
'maxFrameSize': 16385,
'enablePush': false,
'enableConnectProtocol': true
'enableConnectProtocol': true,
'customSettings': { '9999': 301 }
}
});
testUpdateSettingsWith({
Expand Down