1'use strict' 2 3const dns = require('./dns') 4 5const normalizeOptions = (opts) => { 6 const family = parseInt(opts.family ?? '0', 10) 7 const keepAlive = opts.keepAlive ?? true 8 9 const normalized = { 10 // nodejs http agent options. these are all the defaults 11 // but kept here to increase the likelihood of cache hits 12 // https://nodejs.org/api/http.html#new-agentoptions 13 keepAliveMsecs: keepAlive ? 1000 : undefined, 14 maxSockets: opts.maxSockets ?? 15, 15 maxTotalSockets: Infinity, 16 maxFreeSockets: keepAlive ? 256 : undefined, 17 scheduling: 'fifo', 18 // then spread the rest of the options 19 ...opts, 20 // we already set these to their defaults that we want 21 family, 22 keepAlive, 23 // our custom timeout options 24 timeouts: { 25 // the standard timeout option is mapped to our idle timeout 26 // and then deleted below 27 idle: opts.timeout ?? 0, 28 connection: 0, 29 response: 0, 30 transfer: 0, 31 ...opts.timeouts, 32 }, 33 // get the dns options that go at the top level of socket connection 34 ...dns.getOptions({ family, ...opts.dns }), 35 } 36 37 // remove timeout since we already used it to set our own idle timeout 38 delete normalized.timeout 39 40 return normalized 41} 42 43const createKey = (obj) => { 44 let key = '' 45 const sorted = Object.entries(obj).sort((a, b) => a[0] - b[0]) 46 for (let [k, v] of sorted) { 47 if (v == null) { 48 v = 'null' 49 } else if (v instanceof URL) { 50 v = v.toString() 51 } else if (typeof v === 'object') { 52 v = createKey(v) 53 } 54 key += `${k}:${v}:` 55 } 56 return key 57} 58 59const cacheOptions = ({ secureEndpoint, ...options }) => createKey({ 60 secureEndpoint: !!secureEndpoint, 61 // socket connect options 62 family: options.family, 63 hints: options.hints, 64 localAddress: options.localAddress, 65 // tls specific connect options 66 strictSsl: secureEndpoint ? !!options.rejectUnauthorized : false, 67 ca: secureEndpoint ? options.ca : null, 68 cert: secureEndpoint ? options.cert : null, 69 key: secureEndpoint ? options.key : null, 70 // http agent options 71 keepAlive: options.keepAlive, 72 keepAliveMsecs: options.keepAliveMsecs, 73 maxSockets: options.maxSockets, 74 maxTotalSockets: options.maxTotalSockets, 75 maxFreeSockets: options.maxFreeSockets, 76 scheduling: options.scheduling, 77 // timeout options 78 timeouts: options.timeouts, 79 // proxy 80 proxy: options.proxy, 81}) 82 83module.exports = { 84 normalizeOptions, 85 cacheOptions, 86} 87