mirror of
https://github.com/nodejs/node.git
synced 2024-11-22 11:12:18 +00:00
dns: add a cancel() method to the promise Resolver
PR-URL: https://github.com/nodejs/node/pull/33099 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
parent
d5e4e19470
commit
9ea0fae7ea
@ -730,6 +730,14 @@ The following methods from the `dnsPromises` API are available:
|
||||
* [`resolver.reverse()`][`dnsPromises.reverse()`]
|
||||
* [`resolver.setServers()`][`dnsPromises.setServers()`]
|
||||
|
||||
### `resolver.cancel()`
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
Cancel all outstanding DNS queries made by this resolver. The corresponding
|
||||
promises will be rejected with an error with code `ECANCELLED`.
|
||||
|
||||
### `dnsPromises.getServers()`
|
||||
<!-- YAML
|
||||
added: v10.6.0
|
||||
|
@ -217,6 +217,7 @@ class Resolver {
|
||||
|
||||
Resolver.prototype.getServers = CallbackResolver.prototype.getServers;
|
||||
Resolver.prototype.setServers = CallbackResolver.prototype.setServers;
|
||||
Resolver.prototype.cancel = CallbackResolver.prototype.cancel;
|
||||
Resolver.prototype.setLocalAddress = CallbackResolver.prototype.setLocalAddress;
|
||||
Resolver.prototype.resolveAny = resolveMap.ANY = resolver('queryAny');
|
||||
Resolver.prototype.resolve4 = resolveMap.A = resolver('queryA');
|
||||
|
65
test/parallel/test-dns-channel-cancel-promise.js
Normal file
65
test/parallel/test-dns-channel-cancel-promise.js
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const { promises: dnsPromises } = require('dns');
|
||||
const assert = require('assert');
|
||||
const dgram = require('dgram');
|
||||
|
||||
const server = dgram.createSocket('udp4');
|
||||
const resolver = new dnsPromises.Resolver();
|
||||
|
||||
const addMessageListener = () => {
|
||||
server.removeAllListeners('message');
|
||||
|
||||
server.once('message', () => {
|
||||
server.once('message', common.mustNotCall);
|
||||
|
||||
resolver.cancel();
|
||||
});
|
||||
};
|
||||
|
||||
server.bind(0, common.mustCall(async () => {
|
||||
resolver.setServers([`127.0.0.1:${server.address().port}`]);
|
||||
|
||||
addMessageListener();
|
||||
|
||||
// Single promise
|
||||
{
|
||||
const hostname = 'example0.org';
|
||||
|
||||
await assert.rejects(
|
||||
resolver.resolve4(hostname),
|
||||
{
|
||||
code: 'ECANCELLED',
|
||||
syscall: 'queryA',
|
||||
hostname
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
addMessageListener();
|
||||
|
||||
// Multiple promises
|
||||
{
|
||||
const assertions = [];
|
||||
const assertionCount = 10;
|
||||
|
||||
for (let i = 1; i <= assertionCount; i++) {
|
||||
const hostname = `example${i}.org`;
|
||||
|
||||
assertions.push(
|
||||
assert.rejects(
|
||||
resolver.resolve4(hostname),
|
||||
{
|
||||
code: 'ECANCELLED',
|
||||
syscall: 'queryA',
|
||||
hostname: hostname
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.all(assertions);
|
||||
}
|
||||
|
||||
server.close();
|
||||
}));
|
@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const dnstools = require('../common/dns');
|
||||
const { Resolver } = require('dns');
|
||||
const assert = require('assert');
|
||||
const dgram = require('dgram');
|
||||
@ -8,21 +7,45 @@ const dgram = require('dgram');
|
||||
const server = dgram.createSocket('udp4');
|
||||
const resolver = new Resolver();
|
||||
|
||||
server.bind(0, common.mustCall(() => {
|
||||
const desiredQueries = 11;
|
||||
let finishedQueries = 0;
|
||||
|
||||
const addMessageListener = () => {
|
||||
server.removeAllListeners('message');
|
||||
|
||||
server.once('message', () => {
|
||||
server.once('message', common.mustNotCall);
|
||||
|
||||
resolver.cancel();
|
||||
});
|
||||
};
|
||||
|
||||
server.bind(0, common.mustCall(async () => {
|
||||
resolver.setServers([`127.0.0.1:${server.address().port}`]);
|
||||
resolver.resolve4('example.org', common.mustCall((err, res) => {
|
||||
|
||||
const callback = common.mustCall((err, res) => {
|
||||
assert.strictEqual(err.code, 'ECANCELLED');
|
||||
assert.strictEqual(err.syscall, 'queryA');
|
||||
assert.strictEqual(err.hostname, 'example.org');
|
||||
server.close();
|
||||
}));
|
||||
}));
|
||||
assert.strictEqual(err.hostname, `example${finishedQueries}.org`);
|
||||
|
||||
server.on('message', common.mustCall((msg, { address, port }) => {
|
||||
const parsed = dnstools.parseDNSPacket(msg);
|
||||
const domain = parsed.questions[0].domain;
|
||||
assert.strictEqual(domain, 'example.org');
|
||||
finishedQueries++;
|
||||
if (finishedQueries === desiredQueries) {
|
||||
server.close();
|
||||
}
|
||||
}, desiredQueries);
|
||||
|
||||
// Do not send a reply.
|
||||
resolver.cancel();
|
||||
const next = (...args) => {
|
||||
callback(...args);
|
||||
|
||||
addMessageListener();
|
||||
|
||||
// Multiple queries
|
||||
for (let i = 1; i < desiredQueries; i++) {
|
||||
resolver.resolve4(`example${i}.org`, callback);
|
||||
}
|
||||
};
|
||||
|
||||
// Single query
|
||||
addMessageListener();
|
||||
resolver.resolve4('example0.org', next);
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user