Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 02dbcc4

Browse filesBrowse files
Nitzan Uzielydanielleadams
authored andcommitted
net: support abortSignal in server.listen
PR-URL: #36623 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 833e614 commit 02dbcc4
Copy full SHA for 02dbcc4

File tree

Expand file treeCollapse file tree

4 files changed

+70
-1
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+70
-1
lines changed
Open diff view settings
Collapse file

‎doc/api/net.md‎

Copy file name to clipboardExpand all lines: doc/api/net.md
+18Lines changed: 18 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ Listening on a file descriptor is not supported on Windows.
324324
<!-- YAML
325325
added: v0.11.14
326326
changes:
327+
- version: REPLACEME
328+
pr-url: https://github.com/nodejs/node/pull/36623
329+
description: AbortSignal support was added.
327330
- version: v11.4.0
328331
pr-url: https://github.com/nodejs/node/pull/23798
329332
description: The `ipv6Only` option is supported.
@@ -344,6 +347,7 @@ changes:
344347
* `ipv6Only` {boolean} For TCP servers, setting `ipv6Only` to `true` will
345348
disable dual-stack support, i.e., binding to host `::` won't make
346349
`0.0.0.0` be bound. **Default:** `false`.
350+
* `signal` {AbortSignal} An AbortSignal that may be used to close a listening server.
347351
* `callback` {Function}
348352
functions.
349353
* Returns: {net.Server}
@@ -375,6 +379,20 @@ Starting an IPC server as root may cause the server path to be inaccessible for
375379
unprivileged users. Using `readableAll` and `writableAll` will make the server
376380
accessible for all users.
377381

382+
If the `signal` option is enabled, calling `.abort()` on the corresponding
383+
`AbortController` is similar to calling `.close()` on the server:
384+
385+
```js
386+
const controller = new AbortController();
387+
server.listen({
388+
host: 'localhost',
389+
port: 80,
390+
signal: controller.signal
391+
});
392+
// Later, when you want to close the server.
393+
controller.abort();
394+
```
395+
378396
#### `server.listen(path[, backlog][, callback])`
379397
<!-- YAML
380398
added: v0.1.90
Collapse file

‎lib/internal/streams/add-abort-signal.js‎

Copy file name to clipboardExpand all lines: lib/internal/streams/add-abort-signal.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const eos = require('internal/streams/end-of-stream');
99
const { ERR_INVALID_ARG_TYPE } = codes;
1010

1111
// This method is inlined here for readable-stream
12-
// It also does not allow for signal to not exist on the steam
12+
// It also does not allow for signal to not exist on the stream
1313
// https://github.com/nodejs/node/pull/36061#discussion_r533718029
1414
const validateAbortSignal = (signal, name) => {
1515
if (typeof signal !== 'object' ||
Collapse file

‎lib/net.js‎

Copy file name to clipboardExpand all lines: lib/net.js
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ const {
109109
} = require('internal/errors');
110110
const { isUint8Array } = require('internal/util/types');
111111
const {
112+
validateAbortSignal,
112113
validateInt32,
113114
validatePort,
114115
validateString
@@ -1148,6 +1149,22 @@ function afterConnect(status, handle, req, readable, writable) {
11481149
}
11491150
}
11501151

1152+
function addAbortSignalOption(self, options) {
1153+
if (options?.signal === undefined) {
1154+
return;
1155+
}
1156+
validateAbortSignal(options.signal, 'options.signal');
1157+
const { signal } = options;
1158+
const onAborted = () => {
1159+
self.close();
1160+
};
1161+
if (signal.aborted) {
1162+
process.nextTick(onAborted);
1163+
} else {
1164+
signal.addEventListener('abort', onAborted);
1165+
self.once('close', () => signal.removeEventListener('abort', onAborted));
1166+
}
1167+
}
11511168

11521169
function Server(options, connectionListener) {
11531170
if (!(this instanceof Server))
@@ -1398,6 +1415,7 @@ Server.prototype.listen = function(...args) {
13981415
listenInCluster(this, null, -1, -1, backlogFromArgs);
13991416
return this;
14001417
}
1418+
addAbortSignalOption(this, options);
14011419
// (handle[, backlog][, cb]) where handle is an object with a fd
14021420
if (typeof options.fd === 'number' && options.fd >= 0) {
14031421
listenInCluster(this, null, null, null, backlogFromArgs, options.fd);
Collapse file
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
6+
{
7+
// Test bad signal.
8+
const server = net.createServer();
9+
assert.throws(
10+
() => server.listen({ port: 0, signal: 'INVALID_SIGNAL' }),
11+
{
12+
code: 'ERR_INVALID_ARG_TYPE',
13+
name: 'TypeError'
14+
});
15+
}
16+
17+
{
18+
// Test close.
19+
const server = net.createServer();
20+
const controller = new AbortController();
21+
server.on('close', common.mustCall());
22+
server.listen({ port: 0, signal: controller.signal });
23+
controller.abort();
24+
}
25+
26+
{
27+
// Test close with pre-aborted signal.
28+
const server = net.createServer();
29+
const controller = new AbortController();
30+
controller.abort();
31+
server.on('close', common.mustCall());
32+
server.listen({ port: 0, signal: controller.signal });
33+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.