mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
bf37d4be69
This commit gives node.js the ability to also receive custom settings, in addition to sending, them which was implemented before. The custom settings received are limited to setting ids, that were specified before, when creating the session eithers through the server or the client. PR-URL: https://github.com/nodejs/node/pull/51323 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
209 lines
5.7 KiB
JavaScript
209 lines
5.7 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
const assert = require('assert');
|
|
const h2 = require('http2');
|
|
|
|
const server = h2.createServer({
|
|
remoteCustomSettings: [
|
|
55,
|
|
],
|
|
settings: {
|
|
customSettings: {
|
|
1244: 456
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
server.on(
|
|
'stream',
|
|
common.mustCall((stream) => {
|
|
const assertSettings = (settings) => {
|
|
assert.strictEqual(typeof settings, 'object');
|
|
assert.strictEqual(typeof settings.headerTableSize, 'number');
|
|
assert.strictEqual(typeof settings.enablePush, 'boolean');
|
|
assert.strictEqual(typeof settings.initialWindowSize, 'number');
|
|
assert.strictEqual(typeof settings.maxFrameSize, 'number');
|
|
assert.strictEqual(typeof settings.maxConcurrentStreams, 'number');
|
|
assert.strictEqual(typeof settings.maxHeaderListSize, 'number');
|
|
assert.strictEqual(typeof settings.maxHeaderSize, 'number');
|
|
assert.strictEqual(typeof settings.customSettings, 'object');
|
|
let countCustom = 0;
|
|
if (settings.customSettings[55]) {
|
|
assert.strictEqual(typeof settings.customSettings[55], 'number');
|
|
assert.strictEqual(settings.customSettings[55], 12);
|
|
countCustom++;
|
|
}
|
|
if (settings.customSettings[155]) {
|
|
// Should not happen actually
|
|
assert.strictEqual(typeof settings.customSettings[155], 'number');
|
|
countCustom++;
|
|
}
|
|
if (settings.customSettings[1244]) {
|
|
assert.strictEqual(typeof settings.customSettings[1244], 'number');
|
|
assert.strictEqual(settings.customSettings[1244], 456);
|
|
countCustom++;
|
|
}
|
|
assert.strictEqual(countCustom, 1);
|
|
};
|
|
|
|
const localSettings = stream.session.localSettings;
|
|
const remoteSettings = stream.session.remoteSettings;
|
|
assertSettings(localSettings);
|
|
assertSettings(remoteSettings);
|
|
|
|
// Test that stored settings are returned when called for second time
|
|
assert.strictEqual(stream.session.localSettings, localSettings);
|
|
assert.strictEqual(stream.session.remoteSettings, remoteSettings);
|
|
|
|
stream.respond({
|
|
'content-type': 'text/html',
|
|
':status': 200
|
|
});
|
|
stream.end('hello world');
|
|
})
|
|
);
|
|
|
|
server.on('session', (session) => {
|
|
session.settings({
|
|
maxConcurrentStreams: 2
|
|
});
|
|
});
|
|
|
|
server.listen(
|
|
0,
|
|
common.mustCall(() => {
|
|
const client = h2.connect(`http://localhost:${server.address().port}`, {
|
|
settings: {
|
|
enablePush: false,
|
|
initialWindowSize: 123456,
|
|
customSettings: {
|
|
55: 12,
|
|
155: 144 // should not arrive
|
|
},
|
|
},
|
|
remoteCustomSettings: [
|
|
1244,
|
|
]
|
|
});
|
|
|
|
client.on(
|
|
'localSettings',
|
|
common.mustCall((settings) => {
|
|
assert(settings);
|
|
assert.strictEqual(settings.enablePush, false);
|
|
assert.strictEqual(settings.initialWindowSize, 123456);
|
|
assert.strictEqual(settings.maxFrameSize, 16384);
|
|
assert.strictEqual(settings.customSettings[55], 12);
|
|
}, 2)
|
|
);
|
|
|
|
let calledOnce = false;
|
|
client.on(
|
|
'remoteSettings',
|
|
common.mustCall((settings) => {
|
|
assert(settings);
|
|
assert.strictEqual(
|
|
settings.maxConcurrentStreams,
|
|
calledOnce ? 2 : (2 ** 32) - 1
|
|
);
|
|
calledOnce = true;
|
|
}, 2)
|
|
);
|
|
|
|
const headers = { ':path': '/' };
|
|
|
|
const req = client.request(headers);
|
|
|
|
req.on('ready', common.mustCall(() => {
|
|
// pendingSettingsAck will be true if a SETTINGS frame
|
|
// has been sent but we are still waiting for an acknowledgement
|
|
assert(client.pendingSettingsAck);
|
|
}));
|
|
|
|
// State will only be valid after connect event is emitted
|
|
req.on('ready', common.mustCall(() => {
|
|
client.settings({ maxHeaderListSize: 1 }, common.mustCall());
|
|
|
|
// Verify valid error ranges
|
|
[
|
|
['headerTableSize', -1],
|
|
['headerTableSize', 2 ** 32],
|
|
['initialWindowSize', -1],
|
|
['initialWindowSize', 2 ** 32],
|
|
['maxFrameSize', 16383],
|
|
['maxFrameSize', 2 ** 24],
|
|
['maxHeaderListSize', -1],
|
|
['maxHeaderListSize', 2 ** 32],
|
|
['maxHeaderSize', -1],
|
|
['maxHeaderSize', 2 ** 32],
|
|
].forEach(([key, value]) => {
|
|
const settings = {};
|
|
settings[key] = value;
|
|
assert.throws(
|
|
() => client.settings(settings),
|
|
{
|
|
name: 'RangeError',
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
message: `Invalid value for setting "${key}": ${value}`
|
|
}
|
|
);
|
|
});
|
|
|
|
// Same tests as for the client on customSettings
|
|
assert.throws(
|
|
() => client.settings({ customSettings: {
|
|
0x10000: 5,
|
|
} }),
|
|
{
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
name: 'RangeError'
|
|
}
|
|
);
|
|
|
|
assert.throws(
|
|
() => client.settings({ customSettings: {
|
|
55: 0x100000000,
|
|
} }),
|
|
{
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
name: 'RangeError'
|
|
}
|
|
);
|
|
|
|
assert.throws(
|
|
() => client.settings({ customSettings: {
|
|
55: -1,
|
|
} }),
|
|
{
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
name: 'RangeError'
|
|
}
|
|
);
|
|
|
|
// Error checks for enablePush
|
|
[1, {}, 'test', [], null, Infinity, NaN].forEach((i) => {
|
|
assert.throws(
|
|
() => client.settings({ enablePush: i }),
|
|
{
|
|
name: 'TypeError',
|
|
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
message: `Invalid value for setting "enablePush": ${i}`
|
|
}
|
|
);
|
|
});
|
|
}));
|
|
|
|
req.on('response', common.mustCall());
|
|
req.resume();
|
|
req.on('end', common.mustCall(() => {
|
|
server.close();
|
|
client.close();
|
|
}));
|
|
req.end();
|
|
})
|
|
);
|