node/lib/internal/dns/callback_resolver.js
Yagiz Nizipli 8b5cd3248d
dns: call ada::idna::to_ascii directly from c++
PR-URL: https://github.com/nodejs/node/pull/47920
Fixes: https://github.com/nodejs/performance/issues/77
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2023-05-10 16:04:35 +00:00

115 lines
2.7 KiB
JavaScript

'use strict';
const {
ObjectDefineProperty,
ReflectApply,
ArrayPrototypeMap,
Symbol,
} = primordials;
const {
codes: {
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
},
dnsException,
} = require('internal/errors');
const {
createResolverClass,
} = require('internal/dns/utils');
const {
validateFunction,
validateString,
} = require('internal/validators');
const {
QueryReqWrap,
} = internalBinding('cares_wrap');
const {
hasObserver,
startPerf,
stopPerf,
} = require('internal/perf/observe');
const kPerfHooksDnsLookupResolveContext = Symbol('kPerfHooksDnsLookupResolveContext');
function onresolve(err, result, ttls) {
if (ttls && this.ttl)
result = ArrayPrototypeMap(
result, (address, index) => ({ address, ttl: ttls[index] }));
if (err)
this.callback(dnsException(err, this.bindingName, this.hostname));
else {
this.callback(null, result);
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
}
}
}
function resolver(bindingName) {
function query(name, /* options, */ callback) {
let options;
if (arguments.length > 2) {
options = callback;
callback = arguments[2];
}
validateString(name, 'name');
validateFunction(callback, 'callback');
const req = new QueryReqWrap();
req.bindingName = bindingName;
req.callback = callback;
req.hostname = name;
req.oncomplete = onresolve;
req.ttl = !!(options && options.ttl);
const err = this._handle[bindingName](req, name);
if (err) throw dnsException(err, bindingName, name);
if (hasObserver('dns')) {
startPerf(req, kPerfHooksDnsLookupResolveContext, {
type: 'dns',
name: bindingName,
detail: {
host: name,
ttl: req.ttl,
},
});
}
return req;
}
ObjectDefineProperty(query, 'name', { __proto__: null, value: bindingName });
return query;
}
// This is the callback-based resolver. There is another similar
// resolver in dns/promises.js with resolve methods that are based
// on promises instead.
const { Resolver, resolveMap } = createResolverClass(resolver);
Resolver.prototype.resolve = resolve;
function resolve(hostname, rrtype, callback) {
let resolver;
if (typeof rrtype === 'string') {
resolver = resolveMap[rrtype];
} else if (typeof rrtype === 'function') {
resolver = resolveMap.A;
callback = rrtype;
} else {
throw new ERR_INVALID_ARG_TYPE('rrtype', 'string', rrtype);
}
if (typeof resolver === 'function') {
return ReflectApply(resolver, this, [hostname, callback]);
}
throw new ERR_INVALID_ARG_VALUE('rrtype', rrtype);
}
module.exports = {
Resolver,
};