All files / lib/internal/dns callback_resolver.js

98.27% Statements 114/116
87.5% Branches 21/24
100% Functions 4/4
98.27% Lines 114/116

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 11715x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 30x 30x 30x 2x 30x 30x 30x 11x 11x 11x     11x 30x 15x 14547x 14547x 33x 33x 4x 4x 4x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 31x 1x 1x 1x 1x 1x 1x 1x 1x 1x 31x 33x 14547x 14547x 14547x 15x 15x 15x 15x 15x 15x 15x 6x 6x 6x 2x 6x 3x 3x 4x 1x 1x 5x 5x 3x 3x 2x 6x 15x 15x 15x 15x  
'use strict';
 
const {
  ObjectDefineProperty,
  ReflectApply,
  ArrayPrototypeMap,
  Symbol
} = primordials;
 
const { toASCII } = require('internal/idna');
 
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, toASCII(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
};