Skip to content

Commit 588fd0c

Browse files
committed
http, http2: flag for overriding server timeout
Make it possible to override the default http server timeout. Ideally there should be no server timeout - as done on the master branch. This is a non-breaking way to enable platform providers to override the value. Ref: #27558 Ref: #27556 PR-URL: #27704 Refs: #27558 Refs: #27556 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent c0cf173 commit 588fd0c

File tree

10 files changed

+90
-5
lines changed

10 files changed

+90
-5
lines changed

‎doc/api/cli.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ This flag exists to aid in experimentation with the internal implementation of
264264
the Node.js http parser.
265265
This flag is likely to become a no-op and removed at some point in the future.
266266

267+
### `--http-server-default-timeout=milliseconds`
268+
<!-- YAML
269+
added: REPLACEME
270+
-->
271+
272+
Overrides the default value of `http`, `https` and `http2` server socket
273+
timeout. Setting the value to 0 disables server socket timeout. Unless
274+
provided, http server sockets timeout after 120s (2 minutes). Programmatic
275+
setting of the timeout takes precedence over the value set through this
276+
flag.
277+
267278
### `--icu-data-dir=file`
268279
<!-- YAML
269280
added: v0.11.15
@@ -917,6 +928,7 @@ Node.js options that are allowed are:
917928
-`--force-fips`
918929
-`--frozen-intrinsics`
919930
-`--heapsnapshot-signal`
931+
-`--http-server-default-timeout`
920932
-`--icu-data-dir`
921933
-`--inspect`
922934
-`--inspect-brk`

‎doc/api/http.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,9 @@ By default, the Server's timeout value is 2 minutes, and sockets are
10301030
destroyed automatically if they time out. However, if a callback is assigned
10311031
to the Server's `'timeout'` event, timeouts must be handled explicitly.
10321032

1033+
To change the default timeout use the [`--http-server-default-timeout`][]
1034+
flag.
1035+
10331036
### server.timeout
10341037
<!-- YAML
10351038
added: v0.9.12
@@ -1045,6 +1048,9 @@ A value of `0` will disable the timeout behavior on incoming connections.
10451048
The socket timeout logic is set up on connection, so changing this
10461049
value only affects new connections to the server, not any existing connections.
10471050

1051+
To change the default timeout use the [`--http-server-default-timeout`][]
1052+
flag.
1053+
10481054
### server.keepAliveTimeout
10491055
<!-- YAML
10501056
added: v8.0.0
@@ -2150,6 +2156,7 @@ will be emitted in the following order:
21502156
Note that setting the `timeout` option or using the `setTimeout()` function will
21512157
not abort the request or do anything besides add a `'timeout'` event.
21522158

2159+
[`--http-server-default-timeout`]: cli.html#cli_http_server_default_timeout_milliseconds
21532160
[`--max-http-header-size`]: cli.html#cli_max_http_header_size_size
21542161
[`'checkContinue'`]: #http_event_checkcontinue
21552162
[`'request'`]: #http_event_request

‎doc/api/http2.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,9 @@ The `'timeout'` event is emitted when there is no activity on the Server for
17281728
a given number of milliseconds set using `http2server.setTimeout()`.
17291729
**Default:** 2 minutes.
17301730

1731+
To change the default timeout use the [`--http-server-default-timeout`][]
1732+
flag.
1733+
17311734
#### server.close([callback])
17321735
<!-- YAML
17331736
added: v8.4.0
@@ -1758,6 +1761,9 @@ The given callback is registered as a listener on the `'timeout'` event.
17581761
In case of no callback function were assigned, a new `ERR_INVALID_CALLBACK`
17591762
error will be thrown.
17601763

1764+
To change the default timeout use the [`--http-server-default-timeout`][]
1765+
flag.
1766+
17611767
### Class: Http2SecureServer
17621768
<!-- YAML
17631769
added: v8.4.0
@@ -3426,6 +3432,7 @@ following additional properties:
34263432
*`type`{string} Either `'server'` or `'client'` to identify the type of
34273433
`Http2Session`.
34283434

3435+
[`--http-server-default-timeout`]: cli.html#cli_http_server_default_timeout_milliseconds
34293436
[ALPN Protocol ID]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
34303437
[ALPN negotiation]: #http2_alpn_negotiation
34313438
[Compatibility API]: #http2_compatibility_api

‎doc/node.1‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ Chooses an HTTP parser library. Available values are
145145
or
146146
.Sylegacy .
147147
.
148+
.ItFl-http-server-default-timeoutNs=NsArmilliseconds
149+
Overrides the default value for server socket timeout.
150+
.
148151
.ItFl-icu-data-dirNs=NsArfile
149152
Specify ICU data load path.
150153
Overrides

‎lib/_http_server.js‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ const{
5555
DTRACE_HTTP_SERVER_REQUEST,
5656
DTRACE_HTTP_SERVER_RESPONSE
5757
}=require('internal/dtrace');
58+
const{ getOptionValue }=require('internal/options');
5859

5960
constkServerResponse=Symbol('ServerResponse');
61+
constkDefaultHttpServerTimeout=
62+
getOptionValue('--http-server-default-timeout');
6063

6164
constSTATUS_CODES={
6265
100: 'Continue',
@@ -315,7 +318,7 @@ function Server(options, requestListener){
315318

316319
this.on('connection',connectionListener);
317320

318-
this.timeout=2*60*1000;
321+
this.timeout=kDefaultHttpServerTimeout;
319322
this.keepAliveTimeout=5000;
320323
this.maxHeadersCount=null;
321324
this.headersTimeout=40*1000;// 40 seconds

‎lib/https.js‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ const debug = require('internal/util/debuglog').debuglog('https');
3838
const{URL, urlToOptions, searchParamsSymbol }=require('internal/url');
3939
const{ IncomingMessage, ServerResponse }=require('http');
4040
const{ kIncomingMessage }=require('_http_common');
41+
const{ getOptionValue }=require('internal/options');
42+
43+
constkDefaultHttpServerTimeout=
44+
getOptionValue('--http-server-default-timeout');
4145

4246
functionServer(opts,requestListener){
4347
if(!(thisinstanceofServer))returnnewServer(opts,requestListener);
@@ -71,7 +75,7 @@ function Server(opts, requestListener){
7175
conn.destroy(err);
7276
});
7377

74-
this.timeout=2*60*1000;
78+
this.timeout=kDefaultHttpServerTimeout;
7579
this.keepAliveTimeout=5000;
7680
this.maxHeadersCount=null;
7781
this.headersTimeout=40*1000;// 40 seconds

‎lib/internal/http2/core.js‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ const{UV_EOF } = internalBinding('uv');
137137
const{ StreamPipe }=internalBinding('stream_pipe');
138138
const{_connectionListener: httpConnectionListener}=http;
139139
constdebug=require('internal/util/debuglog').debuglog('http2');
140+
const{ getOptionValue }=require('internal/options');
140141

141142
constkMaxFrameSize=(2**24)-1;
142143
constkMaxInt=(2**32)-1;
@@ -171,7 +172,8 @@ const kState = Symbol('state');
171172
constkType=Symbol('type');
172173
constkWriteGeneric=Symbol('write-generic');
173174

174-
constkDefaultSocketTimeout=2*60*1000;
175+
constkDefaultHttpServerTimeout=
176+
getOptionValue('--http-server-default-timeout');
175177

176178
const{
177179
paddingBuffer,
@@ -2679,7 +2681,7 @@ class Http2SecureServer extends TLSServer{
26792681
options=initializeTLSOptions(options);
26802682
super(options,connectionListener);
26812683
this[kOptions]=options;
2682-
this.timeout=kDefaultSocketTimeout;
2684+
this.timeout=kDefaultHttpServerTimeout;
26832685
this.on('newListener',setupCompat);
26842686
if(typeofrequestListener==='function')
26852687
this.on('request',requestListener);
@@ -2701,7 +2703,7 @@ class Http2Server extends NETServer{
27012703
constructor(options,requestListener){
27022704
super(connectionListener);
27032705
this[kOptions]=initializeOptions(options);
2704-
this.timeout=kDefaultSocketTimeout;
2706+
this.timeout=kDefaultHttpServerTimeout;
27052707
this.on('newListener',setupCompat);
27062708
if(typeofrequestListener==='function')
27072709
this.on('request',requestListener);

‎src/node_options.cc‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser(){
308308
"(default: llhttp).",
309309
&EnvironmentOptions::http_parser,
310310
kAllowedInEnvironment);
311+
AddOption("--http-server-default-timeout",
312+
"Default http server socket timeout in ms "
313+
"(default: 120000)",
314+
&EnvironmentOptions::http_server_default_timeout,
315+
kAllowedInEnvironment);
311316
AddOption("--input-type",
312317
"set module type for string input",
313318
&EnvironmentOptions::module_type,

‎src/node_options.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class EnvironmentOptions : public Options{
102102
bool frozen_intrinsics = false;
103103
std::string heap_snapshot_signal;
104104
std::string http_parser = "llhttp";
105+
uint64_t http_server_default_timeout = 120000;
105106
bool no_deprecation = false;
106107
bool no_force_async_hooks_checks = false;
107108
bool no_warnings = false;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
4+
if(!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
constfixtures=require('../common/fixtures');
8+
consthttp=require('http');
9+
consthttps=require('https');
10+
consthttp2=require('http2');
11+
constassert=require('assert');
12+
const{ spawnSync }=require('child_process');
13+
14+
// Make sure the defaults are correct.
15+
constservers=[
16+
http.createServer(),
17+
https.createServer({
18+
key: fixtures.readKey('agent1-key.pem'),
19+
cert: fixtures.readKey('agent1-cert.pem')
20+
}),
21+
http2.createServer()
22+
];
23+
24+
for(constserverofservers){
25+
assert.strictEqual(server.timeout,120000);
26+
server.close();
27+
}
28+
29+
// Ensure that command line flag overrides the default timeout.
30+
constchild1=spawnSync(process.execPath,['--http-server-default-timeout=10',
31+
'-p','http.createServer().timeout'
32+
]);
33+
assert.strictEqual(+child1.stdout.toString().trim(),10);
34+
35+
// Ensure that the flag is whitelisted for NODE_OPTIONS.
36+
constenv=Object.assign({},process.env,{
37+
NODE_OPTIONS: '--http-server-default-timeout=10'
38+
});
39+
constchild2=spawnSync(process.execPath,
40+
['-p','http.createServer().timeout'],{ env });
41+
assert.strictEqual(+child2.stdout.toString().trim(),10);

0 commit comments

Comments
(0)