Skip to content

Commit a6e7e6a

Browse files
authored
net: runtime-deprecate Server.prototype._listen2
Signed-off-by: Guilherme Araújo <arauujogui@gmail.com> PR-URL: #64794 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Tim Perry <pimterry@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent d1f3d0a commit a6e7e6a

5 files changed

Lines changed: 98 additions & 8 deletions

File tree

doc/api/deprecations.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4697,6 +4697,23 @@ underlying stream are emitted from `req`. On the write-side you can use
46974697
`res.writableFinished` to confirm whether the response was written
46984698
successfully before the response closed.
46994699
4700+
### DEP0208: `Server.prototype._listen2`
4701+
4702+
<!-- YAML
4703+
changes:
4704+
- version: REPLACEME
4705+
pr-url: https://github.com/nodejs/node/pull/64794
4706+
description: Runtime deprecation.
4707+
-->
4708+
4709+
Type: Runtime
4710+
4711+
`net.Server.prototype._listen2` is an undocumented alias for an internal
4712+
function that sets up the listening handle. It is kept only so that code
4713+
replacing it keeps being called by [`server.listen()`][], and it will be
4714+
removed in a future version of Node.js. Use [`server.listen()`][] instead of
4715+
calling or overriding `_listen2`.
4716+
47004717
[DEP0142]: #dep0142-repl_builtinlibs
47014718
[DEP0156]: #dep0156-aborted-property-and-abort-aborted-event-in-http
47024719
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
@@ -4814,6 +4831,7 @@ successfully before the response closed.
48144831
[`response.writableEnded`]: http.md#responsewritableended
48154832
[`response.writableFinished`]: http.md#responsewritablefinished
48164833
[`script.createCachedData()`]: vm.md#scriptcreatecacheddata
4834+
[`server.listen()`]: net.md#serverlisten
48174835
[`setInterval()`]: timers.md#setintervalcallback-delay-args
48184836
[`setTimeout()`]: timers.md#settimeoutcallback-delay-args
48194837
[`socket.bufferSize`]: net.md#socketbuffersize

lib/net.js

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const {
133133
const { isUint8Array } = require('internal/util/types');
134134
const { queueMicrotask } = require('internal/process/task_queues');
135135
const {
136+
deprecate,
136137
guessHandleType,
137138
isWindows,
138139
kEmptyObject,
@@ -2357,7 +2358,27 @@ function setupListenHandle(address, port, addressType, backlog, fd, flags) {
23572358
this);
23582359
}
23592360

2360-
Server.prototype._listen2 = setupListenHandle; // legacy alias
2361+
// Legacy alias for `setupListenHandle`, kept around only because it is an
2362+
// undocumented monkeypatch point. Nothing in core calls it unless it has been
2363+
// overridden, see `callSetupListenHandle`.
2364+
const legacyListen2 = deprecate(
2365+
setupListenHandle,
2366+
'Server.prototype._listen2 is deprecated. Use Server.prototype.listen() instead.',
2367+
'DEP0208');
2368+
Server.prototype._listen2 = legacyListen2;
2369+
2370+
// Set up the listen handle, going through `_listen2` when userland replaced it
2371+
// so that the monkeypatch keeps taking effect (DEP0208). Servers that did not
2372+
// touch `_listen2` must not trigger the deprecation warning.
2373+
function callSetupListenHandle(server, address, port, addressType, backlog,
2374+
fd, flags) {
2375+
if (server._listen2 !== legacyListen2) {
2376+
server._listen2(address, port, addressType, backlog, fd, flags);
2377+
return;
2378+
}
2379+
FunctionPrototypeCall(setupListenHandle, server, address, port, addressType,
2380+
backlog, fd, flags);
2381+
}
23612382

23622383
// A listening TCP Server can be transferred to another thread, which moves the
23632384
// underlying listening socket (and its pending accept queue) to that thread's
@@ -2431,9 +2452,8 @@ function listenInCluster(server, address, port, addressType,
24312452

24322453
if (cluster.isPrimary || exclusive) {
24332454
// Will create a new handle
2434-
// _listen2 sets up the listened handle, it is still named like this
2435-
// to avoid breaking code that wraps this method
2436-
server._listen2(address, port, addressType, backlog, fd, flags);
2455+
callSetupListenHandle(server, address, port, addressType, backlog, fd,
2456+
flags);
24372457
return;
24382458
}
24392459

@@ -2467,9 +2487,8 @@ function listenInCluster(server, address, port, addressType,
24672487
}
24682488
// Reuse primary's server handle
24692489
server._handle = handle;
2470-
// _listen2 sets up the listened handle, it is still named like this
2471-
// to avoid breaking code that wraps this method
2472-
server._listen2(address, port, addressType, backlog, fd, flags);
2490+
callSetupListenHandle(server, address, port, addressType, backlog, fd,
2491+
flags);
24732492
}
24742493
}
24752494

test/parallel/test-net-listen-handle-in-cluster-2.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ if (cluster.isPrimary) {
1414
const handle = new TCP(TCPConstants.SOCKET);
1515
const errno = handle.bind('0.0.0.0', 0);
1616
assert.strictEqual(errno, 0);
17-
// Execute _listen2 instead of cluster._getServer in listenInCluster
17+
// Set up the listen handle directly instead of going through
18+
// cluster._getServer in listenInCluster
1819
net.createServer().listen(handle, common.mustCall(() => {
1920
process.exit(0);
2021
}));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
6+
// `Server.prototype._listen2` is a deprecated alias for the internal function
7+
// that sets up the listening handle (DEP0208).
8+
9+
common.expectWarning(
10+
'DeprecationWarning',
11+
'Server.prototype._listen2 is deprecated. Use Server.prototype.listen() instead.',
12+
'DEP0208');
13+
14+
// Listening without touching `_listen2` must not emit the warning.
15+
const server = net.createServer();
16+
server.listen(0, common.mustCall(() => {
17+
server.close(common.mustCall(() => {
18+
// Calling the alias directly emits the warning. It still sets up the
19+
// handle, so the server ends up listening.
20+
const legacy = net.createServer();
21+
legacy.on('listening', common.mustCall(() => {
22+
assert.strictEqual(legacy.listening, true);
23+
legacy.close();
24+
}));
25+
legacy._listen2(null, 0, 4, undefined, undefined, 0);
26+
}));
27+
}));
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
6+
// Overriding the deprecated `Server.prototype._listen2` alias (DEP0208) is
7+
// still honored by `server.listen()`.
8+
9+
common.expectWarning(
10+
'DeprecationWarning',
11+
'Server.prototype._listen2 is deprecated. Use Server.prototype.listen() instead.',
12+
'DEP0208');
13+
14+
const original = net.Server.prototype._listen2;
15+
net.Server.prototype._listen2 = common.mustCall(function(...args) {
16+
assert.strictEqual(this, server);
17+
assert.deepStrictEqual(args, [null, 0, 4, 0, undefined, 0]);
18+
return original.apply(this, args);
19+
});
20+
21+
const server = net.createServer();
22+
server.listen(0, common.mustCall(() => {
23+
net.Server.prototype._listen2 = original;
24+
server.close();
25+
}));

0 commit comments

Comments
 (0)