options.js 2.4 KB

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