Skip to content

Commit 4fa7739

Browse files
HinataKah0targos
authored andcommitted
http: add highWaterMark opt in http.createServer
Add highWaterMark option when creating a new HTTP server. This option will override the default (readable|writable) highWaterMark values on sockets created. Fixes: #46606 PR-URL: #47405 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
1 parent 21ff331 commit 4fa7739

7 files changed

Lines changed: 84 additions & 6 deletions

File tree

‎doc/api/http.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,6 +3192,9 @@ Found'`.
31923192
<!-- YAML
31933193
added: v0.1.13
31943194
changes:
3195+
- version: REPLACEME
3196+
pr-url: https://github.com/nodejs/node/pull/47405
3197+
description: The `highWaterMark` option is supported now.
31953198
- version: v18.0.0
31963199
pr-url: https://github.com/nodejs/node/pull/41263
31973200
description: The `requestTimeout`, `headersTimeout`, `keepAliveTimeout`, and
@@ -3229,6 +3232,10 @@ changes:
32293232
the complete HTTP headers from the client.
32303233
See [`server.headersTimeout`][] for more information.
32313234
**Default:**`60000`.
3235+
*`highWaterMark` {number} Optionally overrides all `socket`s'
3236+
`readableHighWaterMark` and `writableHighWaterMark`. This affects
3237+
`highWaterMark` property of both `IncomingMessage` and `ServerResponse`.
3238+
**Default:** See [`stream.getDefaultHighWaterMark()`][].
32323239
*`insecureHTTPParser` {boolean} Use an insecure HTTP parser that accepts
32333240
invalid HTTP headers when `true`. Using the insecure parser should be
32343241
avoided. See [`--insecure-http-parser`][] for more information.
@@ -3898,6 +3905,7 @@ Set the maximum number of idle HTTP parsers.
38983905
[`socket.setNoDelay()`]: net.md#socketsetnodelaynodelay
38993906
[`socket.setTimeout()`]: net.md#socketsettimeouttimeout-callback
39003907
[`socket.unref()`]: net.md#socketunref
3908+
[`stream.getDefaultHighWaterMark()`]: stream.md#streamgetdefaulthighwatermarkobjectmode
39013909
[`url.parse()`]: url.md#urlparseurlstring-parsequerystring-slashesdenotehost
39023910
[`writable.cork()`]: stream.md#writablecork
39033911
[`writable.destroy()`]: stream.md#writabledestroyerror

‎doc/api/net.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,9 @@ then returns the `net.Socket` that starts the connection.
15391539
<!-- YAML
15401540
added: v0.5.0
15411541
changes:
1542+
- version: REPLACEME
1543+
pr-url: https://github.com/nodejs/node/pull/47405
1544+
description: The `highWaterMark` option is supported now.
15421545
- version:
15431546
- v17.7.0
15441547
- v16.15.0
@@ -1551,6 +1554,9 @@ changes:
15511554
*`allowHalfOpen` {boolean} If set to `false`, then the socket will
15521555
automatically end the writable side when the readable side ends.
15531556
**Default:**`false`.
1557+
*`highWaterMark` {number} Optionally overrides all [`net.Socket`][]s'
1558+
`readableHighWaterMark` and `writableHighWaterMark`.
1559+
**Default:** See [`stream.getDefaultHighWaterMark()`][].
15541560
*`pauseOnConnect` {boolean} Indicates whether the socket should be
15551561
paused on incoming connections. **Default:**`false`.
15561562
*`noDelay` {boolean} If set to `true`, it disables the use of Nagle's algorithm immediately
@@ -1780,6 +1786,7 @@ net.isIPv6('fhqwhgads'); // returns false
17801786
[`socket.setKeepAlive(enable, initialDelay)`]: #socketsetkeepaliveenable-initialdelay
17811787
[`socket.setTimeout()`]: #socketsettimeouttimeout-callback
17821788
[`socket.setTimeout(timeout)`]: #socketsettimeouttimeout-callback
1789+
[`stream.getDefaultHighWaterMark()`]: stream.md#streamgetdefaulthighwatermarkobjectmode
17831790
[`writable.destroy()`]: stream.md#writabledestroyerror
17841791
[`writable.destroyed`]: stream.md#writabledestroyed
17851792
[`writable.end()`]: stream.md#writableendchunk-encoding-callback

‎lib/_http_outgoing.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ function isContentDispositionField(s) {
101101
returns.length===19&&StringPrototypeToLowerCase(s)==='content-disposition';
102102
}
103103

104-
functionOutgoingMessage(){
104+
functionOutgoingMessage(options){
105105
Stream.call(this);
106106

107107
// Queue that holds all currently pending data, until the response will be
@@ -149,7 +149,7 @@ function OutgoingMessage() {
149149
this._onPendingData=nop;
150150

151151
this[kErrored]=null;
152-
this[kHighWaterMark]=getDefaultHighWaterMark();
152+
this[kHighWaterMark]=options?.highWaterMark??getDefaultHighWaterMark();
153153
}
154154
ObjectSetPrototypeOf(OutgoingMessage.prototype,Stream.prototype);
155155
ObjectSetPrototypeOf(OutgoingMessage,Stream);
@@ -1171,6 +1171,7 @@ function(err, event) {
11711171
};
11721172

11731173
module.exports={
1174+
kHighWaterMark,
11741175
kUniqueHeaders,
11751176
parseUniqueHeadersOption,
11761177
validateHeaderName,

‎lib/_http_server.js‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ class HTTPServerAsyncResource {
188188
}
189189
}
190190

191-
functionServerResponse(req){
192-
OutgoingMessage.call(this);
191+
functionServerResponse(req,options){
192+
OutgoingMessage.call(this,options);
193193

194194
if(req.method==='HEAD')this._hasBody=false;
195195

@@ -513,7 +513,8 @@ function Server(options, requestListener) {
513513
this,
514514
{allowHalfOpen: true,noDelay: options.noDelay??true,
515515
keepAlive: options.keepAlive,
516-
keepAliveInitialDelay: options.keepAliveInitialDelay});
516+
keepAliveInitialDelay: options.keepAliveInitialDelay,
517+
highWaterMark: options.highWaterMark});
517518

518519
if(requestListener){
519520
this.on('request',requestListener);
@@ -1019,7 +1020,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
10191020
}
10201021
}
10211022

1022-
constres=newserver[kServerResponse](req);
1023+
constres=newserver[kServerResponse](req,{highWaterMark: socket.writableHighWaterMark});
10231024
res._keepAliveTimeout=server.keepAliveTimeout;
10241025
res._maxRequestsPerSocket=server.maxRequestsPerSocket;
10251026
res._onPendingData=updateOutgoingData.bind(undefined,

‎lib/http.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ let maxHeaderSize;
5454
* maxHeaderSize?: number;
5555
* requireHostHeader?: boolean;
5656
* joinDuplicateHeaders?: boolean;
57+
* highWaterMark?: number;
5758
* }} [opts]
5859
* @param {Function} [requestListener]
5960
* @returns {Server}

‎lib/net.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ const {
154154
startPerf,
155155
stopPerf,
156156
}=require('internal/perf/observe');
157+
const{ getDefaultHighWaterMark }=require('internal/streams/state');
157158

158159
functiongetFlags(ipv6Only){
159160
returnipv6Only===true ? TCPConstants.UV_TCP_IPV6ONLY : 0;
@@ -1682,6 +1683,15 @@ function Server(options, connectionListener) {
16821683
options.keepAliveInitialDelay=0;
16831684
}
16841685
}
1686+
if(typeofoptions.highWaterMark!=='undefined'){
1687+
validateNumber(
1688+
options.highWaterMark,'options.highWaterMark',
1689+
);
1690+
1691+
if(options.highWaterMark<0){
1692+
options.highWaterMark=getDefaultHighWaterMark();
1693+
}
1694+
}
16851695

16861696
this._connections=0;
16871697

@@ -1696,6 +1706,7 @@ function Server(options, connectionListener) {
16961706
this.noDelay=Boolean(options.noDelay);
16971707
this.keepAlive=Boolean(options.keepAlive);
16981708
this.keepAliveInitialDelay=~~(options.keepAliveInitialDelay/1000);
1709+
this.highWaterMark=options.highWaterMark??getDefaultHighWaterMark();
16991710
}
17001711
ObjectSetPrototypeOf(Server.prototype,EventEmitter.prototype);
17011712
ObjectSetPrototypeOf(Server,EventEmitter);
@@ -2077,6 +2088,8 @@ function onconnection(err, clientHandle) {
20772088
pauseOnCreate: self.pauseOnConnect,
20782089
readable: true,
20792090
writable: true,
2091+
readableHighWaterMark: self.highWaterMark,
2092+
writableHighWaterMark: self.highWaterMark,
20802093
});
20812094

20822095
if(self.noDelay&&clientHandle.setNoDelay){
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
constcommon=require('../common');
4+
constassert=require('assert');
5+
consthttp=require('http');
6+
const{ kHighWaterMark }=require('_http_outgoing');
7+
8+
const{ getDefaultHighWaterMark }=require('internal/streams/state');
9+
10+
functionlisten(server){
11+
server.listen(0,common.mustCall(()=>{
12+
http.get({
13+
port: server.address().port,
14+
},(res)=>{
15+
assert.strictEqual(res.statusCode,200);
16+
res.resume().on('end',common.mustCall(()=>{
17+
server.close();
18+
}));
19+
});
20+
}));
21+
}
22+
23+
{
24+
constserver=http.createServer({
25+
highWaterMark: getDefaultHighWaterMark()*2,
26+
},common.mustCall((req,res)=>{
27+
assert.strictEqual(req._readableState.highWaterMark,getDefaultHighWaterMark()*2);
28+
assert.strictEqual(res[kHighWaterMark],getDefaultHighWaterMark()*2);
29+
res.statusCode=200;
30+
res.end();
31+
}));
32+
33+
listen(server);
34+
}
35+
36+
{
37+
constserver=http.createServer(
38+
common.mustCall((req,res)=>{
39+
assert.strictEqual(req._readableState.highWaterMark,getDefaultHighWaterMark());
40+
assert.strictEqual(res[kHighWaterMark],getDefaultHighWaterMark());
41+
res.statusCode=200;
42+
res.end();
43+
})
44+
);
45+
46+
listen(server);
47+
}

0 commit comments

Comments
 (0)