Skip to content

Commit 45d712c

Browse files
preyunkaddaleax
authored andcommitted
http2: add maxHeaderSize option to http2
add maxHeaderSize to http2 as an alias for maxHeaderListSize. Fixes: #33517 PR-URL: #33636 Reviewed-By: Zeyu Yang <[email protected]> Reviewed-By: Pranshu Srivastava <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 653d88a commit 45d712c

7 files changed

+54
-26
lines changed

doc/api/http2.md

+1
Original file line numberDiff line numberDiff line change
@@ -2518,6 +2518,7 @@ properties.
25182518
* `maxHeaderListSize` {number} Specifies the maximum size (uncompressed octets)
25192519
of header list that will be accepted. The minimum allowed value is 0. The
25202520
maximum allowed value is 2<sup>32</sup>-1. **Default:** `65535`.
2521+
* `maxHeaderSize` {number} Alias for `maxHeaderListSize`.
25212522
* `enableConnectProtocol`{boolean} Specifies `true` if the "Extended Connect
25222523
Protocol" defined by [RFC 8441][] is to be enabled. This setting is only
25232524
meaningful if sent by the server. Once the `enableConnectProtocol` setting

lib/internal/http2/core.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,9 @@ const validateSettings = hideStackFrames((settings) => {
925925
assertWithinRange('maxHeaderListSize',
926926
settings.maxHeaderListSize,
927927
0, kMaxInt);
928+
assertWithinRange('maxHeaderSize',
929+
settings.maxHeaderSize,
930+
0, kMaxInt);
928931
if (settings.enablePush !== undefined &&
929932
typeof settings.enablePush !== 'boolean') {
930933
throw new ERR_HTTP2_INVALID_SETTING_VALUE('enablePush',
@@ -3085,7 +3088,7 @@ function getUnpackedSettings(buf, options = {}) {
30853088
settings.maxFrameSize = value;
30863089
break;
30873090
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
3088-
settings.maxHeaderListSize = value;
3091+
settings.maxHeaderListSize = settings.maxHeaderSize = value;
30893092
break;
30903093
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
30913094
settings.enableConnectProtocol = value !== 0;

lib/internal/http2/util.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ function getDefaultSettings() {
300300

301301
if ((flags & (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) ===
302302
(1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) {
303-
holder.maxHeaderListSize =
303+
holder.maxHeaderListSize = holder.maxHeaderSize =
304304
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE];
305305
}
306306

@@ -328,6 +328,7 @@ function getSettings(session, remote) {
328328
maxFrameSize: settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE],
329329
maxConcurrentStreams: settingsBuffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS],
330330
maxHeaderListSize: settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE],
331+
maxHeaderSize: settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE],
331332
enableConnectProtocol:
332333
!!settingsBuffer[IDX_SETTINGS_ENABLE_CONNECT_PROTOCOL]
333334
};
@@ -355,10 +356,20 @@ function updateSettingsBuffer(settings) {
355356
settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
356357
settings.maxFrameSize;
357358
}
358-
if (typeof settings.maxHeaderListSize === 'number') {
359+
if (typeof settings.maxHeaderListSize === 'number' ||
360+
typeof settings.maxHeaderSize === 'number') {
359361
flags |= (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE);
360-
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
361-
settings.maxHeaderListSize;
362+
if (settings.maxHeaderSize !== undefined &&
363+
(settings.maxHeaderSize !== settings.maxHeaderListSize)) {
364+
process.emitWarning(
365+
'settings.maxHeaderSize overwrite settings.maxHeaderListSize'
366+
);
367+
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
368+
settings.maxHeaderSize;
369+
} else {
370+
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
371+
settings.maxHeaderListSize;
372+
}
362373
}
363374
if (typeof settings.enablePush === 'boolean') {
364375
flags |= (1 << IDX_SETTINGS_ENABLE_PUSH);

test/parallel/test-http2-client-settings-before-connect.js

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ server.listen(0, common.mustCall(() => {
3232
['maxConcurrentStreams', 2 ** 32, RangeError],
3333
['maxHeaderListSize', -1, RangeError],
3434
['maxHeaderListSize', 2 ** 32, RangeError],
35+
['maxHeaderSize', -1, RangeError],
36+
['maxHeaderSize', 2 ** 32, RangeError],
3537
['enablePush', 'a', TypeError],
3638
['enablePush', 1, TypeError],
3739
['enablePush', 0, TypeError],

test/parallel/test-http2-getpackedsettings.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ assert.deepStrictEqual(val, check);
2626
['maxConcurrentStreams', 0],
2727
['maxConcurrentStreams', 2 ** 31 - 1],
2828
['maxHeaderListSize', 0],
29-
['maxHeaderListSize', 2 ** 32 - 1]
29+
['maxHeaderListSize', 2 ** 32 - 1],
30+
['maxHeaderSize', 0],
31+
['maxHeaderSize', 2 ** 32 - 1]
3032
].forEach((i) => {
3133
// Valid options should not throw.
3234
http2.getPackedSettings({ [i[0]]: i[1] });
@@ -45,7 +47,9 @@ http2.getPackedSettings({ enablePush: false });
4547
['maxConcurrentStreams', -1],
4648
['maxConcurrentStreams', 2 ** 32],
4749
['maxHeaderListSize', -1],
48-
['maxHeaderListSize', 2 ** 32]
50+
['maxHeaderListSize', 2 ** 32],
51+
['maxHeaderSize', -1],
52+
['maxHeaderSize', 2 ** 32]
4953
].forEach((i) => {
5054
assert.throws(() => {
5155
http2.getPackedSettings({ [i[0]]: i[1] });
@@ -96,6 +100,7 @@ http2.getPackedSettings({ enablePush: false });
96100
maxFrameSize: 20000,
97101
maxConcurrentStreams: 200,
98102
maxHeaderListSize: 100,
103+
maxHeaderSize: 100,
99104
enablePush: true,
100105
enableConnectProtocol: false,
101106
foo: 'ignored'
@@ -148,6 +153,7 @@ http2.getPackedSettings({ enablePush: false });
148153
assert.strictEqual(settings.maxFrameSize, 20000);
149154
assert.strictEqual(settings.maxConcurrentStreams, 200);
150155
assert.strictEqual(settings.maxHeaderListSize, 100);
156+
assert.strictEqual(settings.maxHeaderSize, 100);
151157
assert.strictEqual(settings.enablePush, true);
152158
assert.strictEqual(settings.enableConnectProtocol, false);
153159
}

test/parallel/test-http2-session-settings.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ server.on(
1919
assert.strictEqual(typeof settings.maxFrameSize, 'number');
2020
assert.strictEqual(typeof settings.maxConcurrentStreams, 'number');
2121
assert.strictEqual(typeof settings.maxHeaderListSize, 'number');
22+
assert.strictEqual(typeof settings.maxHeaderSize, 'number');
2223
};
2324

2425
const localSettings = stream.session.localSettings;
@@ -100,7 +101,9 @@ server.listen(
100101
['maxFrameSize', 16383],
101102
['maxFrameSize', 2 ** 24],
102103
['maxHeaderListSize', -1],
103-
['maxHeaderListSize', 2 ** 32]
104+
['maxHeaderListSize', 2 ** 32],
105+
['maxHeaderSize', -1],
106+
['maxHeaderSize', 2 ** 32]
104107
].forEach((i) => {
105108
const settings = {};
106109
settings[i[0]] = i[1];

test/parallel/test-http2-too-large-headers.js

+20-18
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,26 @@ const {
99
NGHTTP2_ENHANCE_YOUR_CALM
1010
} = http2.constants;
1111

12-
const server = http2.createServer({ settings: { maxHeaderListSize: 100 } });
13-
server.on('stream', common.mustNotCall());
12+
for (const prototype of ['maxHeaderListSize', 'maxHeaderSize']) {
13+
const server = http2.createServer({ settings: { [prototype]: 100 } });
14+
server.on('stream', common.mustNotCall());
1415

15-
server.listen(0, common.mustCall(() => {
16-
const client = http2.connect(`http://localhost:${server.address().port}`);
16+
server.listen(0, common.mustCall(() => {
17+
const client = http2.connect(`http://localhost:${server.address().port}`);
1718

18-
client.on('remoteSettings', () => {
19-
const req = client.request({ 'foo': 'a'.repeat(1000) });
20-
req.on('error', common.expectsError({
21-
code: 'ERR_HTTP2_STREAM_ERROR',
22-
name: 'Error',
23-
message: 'Stream closed with error code NGHTTP2_ENHANCE_YOUR_CALM'
24-
}));
25-
req.on('close', common.mustCall(() => {
26-
assert.strictEqual(req.rstCode, NGHTTP2_ENHANCE_YOUR_CALM);
27-
server.close();
28-
client.close();
29-
}));
30-
});
19+
client.on('remoteSettings', () => {
20+
const req = client.request({ 'foo': 'a'.repeat(1000) });
21+
req.on('error', common.expectsError({
22+
code: 'ERR_HTTP2_STREAM_ERROR',
23+
name: 'Error',
24+
message: 'Stream closed with error code NGHTTP2_ENHANCE_YOUR_CALM'
25+
}));
26+
req.on('close', common.mustCall(() => {
27+
assert.strictEqual(req.rstCode, NGHTTP2_ENHANCE_YOUR_CALM);
28+
server.close();
29+
client.close();
30+
}));
31+
});
3132

32-
}));
33+
}));
34+
}

0 commit comments

Comments
 (0)