Skip to content

Commit

Permalink
http2: add updateSettings to both http2 servers
Browse files Browse the repository at this point in the history
Allow the user to update the server settings
after using http2.createSecureServer() or
after using http2.createServer().

Fixes: #35353

PR-URL: #35383
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
  • Loading branch information
Vincent Boivin authored and targos committed May 1, 2021
1 parent d63747d commit 2e25922
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
26 changes: 26 additions & 0 deletions doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,19 @@ A value of `0` will disable the timeout behavior on incoming connections.
The socket timeout logic is set up on connection, so changing this
value only affects new connections to the server, not any existing connections.

#### `server.updateSettings([settings])`
<!-- YAML
added: REPLACEME
-->

* `settings` {HTTP/2 Settings Object}

Used to update the server with the provided settings.

Throws `ERR_HTTP2_INVALID_SETTING_VALUE` for invalid `settings` values.

Throws `ERR_INVALID_ARG_TYPE` for invalid `settings` argument.

### Class: `Http2SecureServer`
<!-- YAML
added: v8.4.0
Expand Down Expand Up @@ -2059,6 +2072,19 @@ A value of `0` will disable the timeout behavior on incoming connections.
The socket timeout logic is set up on connection, so changing this
value only affects new connections to the server, not any existing connections.

#### `server.updateSettings([settings])`
<!-- YAML
added: REPLACEME
-->

* `settings` {HTTP/2 Settings Object}

Used to update the server with the provided settings.

Throws `ERR_HTTP2_INVALID_SETTING_VALUE` for invalid `settings` values.

Throws `ERR_INVALID_ARG_TYPE` for invalid `settings` argument.

### `http2.createServer(options[, onRequestHandler])`
<!-- YAML
added: v8.4.0
Expand Down
12 changes: 12 additions & 0 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,12 @@ class Http2SecureServer extends TLSServer {
}
return this;
}

updateSettings(settings) {
assertIsObject(settings, 'settings');
validateSettings(settings);
this[kOptions].settings = { ...this[kOptions].settings, ...settings };
}
}

class Http2Server extends NETServer {
Expand All @@ -3033,6 +3039,12 @@ class Http2Server extends NETServer {
}
return this;
}

updateSettings(settings) {
assertIsObject(settings, 'settings');
validateSettings(settings);
this[kOptions].settings = { ...this[kOptions].settings, ...settings };
}
}

Http2Server.prototype[EventEmitter.captureRejectionSymbol] = function(
Expand Down
59 changes: 59 additions & 0 deletions test/parallel/test-http2-update-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

// This test ensures that the Http2SecureServer and Http2Server
// settings are updated when the setting object is valid.
// When the setting object is invalid, this test ensures that
// updateSettings throws an exception.

const common = require('../common');
if (!common.hasCrypto) { common.skip('missing crypto'); }
const assert = require('assert');
const http2 = require('http2');

testUpdateSettingsWith({
server: http2.createSecureServer(),
newServerSettings: {
'headerTableSize': 1,
'initialWindowSize': 1,
'maxConcurrentStreams': 1,
'maxHeaderListSize': 1,
'maxFrameSize': 16385,
'enablePush': false,
'enableConnectProtocol': true
}
});
testUpdateSettingsWith({
server: http2.createServer(),
newServerSettings: {
'enablePush': false
}
});

function testUpdateSettingsWith({ server, newServerSettings }) {
const oldServerSettings = getServerSettings(server);
assert.notDeepStrictEqual(oldServerSettings, newServerSettings);
server.updateSettings(newServerSettings);
const updatedServerSettings = getServerSettings(server);
assert.deepStrictEqual(updatedServerSettings, { ...oldServerSettings,
...newServerSettings });
assert.throws(() => server.updateSettings(''), {
message: 'The "settings" argument must be of type object. ' +
'Received type string (\'\')',
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError'
});
assert.throws(() => server.updateSettings({
'maxHeaderListSize': 'foo'
}), {
message: 'Invalid value for setting "maxHeaderListSize": foo',
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
name: 'RangeError'
});
}

function getServerSettings(server) {
const options = Object
.getOwnPropertySymbols(server)
.find((s) => s.toString() === 'Symbol(options)');
return server[options].settings;
}

0 comments on commit 2e25922

Please sign in to comment.