Agent.js.map 12.2 KB
{"version":3,"sources":["../../src/classes/Agent.js"],"names":["log","Logger","child","namespace","requestId","Agent","constructor","isProxyConfigured","mustUrlUseProxy","getUrlProxy","fallbackAgent","socketConnectionTimeout","addRequest","request","configuration","requestUrl","path","startsWith","protocol","hostname","host","port","trace","destination","currentRequestId","proxy","authorization","setHeader","Buffer","from","toString","on","error","once","response","headers","statusCode","shouldKeepAlive","connectionConfiguration","tls","ca","cert","ciphers","clientCertEngine","crl","dhparam","ecdhCurve","honorCipherOrder","key","passphrase","pfx","rejectUnauthorized","secureOptions","secureProtocol","servername","sessionIdContext","process","env","NODE_TLS_REJECT_UNAUTHORIZED","createConnection","socket","target","setTimeout","destroy","emit","debug","socketError","onSocket"],"mappings":"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","sourcesContent":["// @flow\n\nimport {\n  serializeError,\n} from 'serialize-error';\nimport {\n  boolean,\n} from 'boolean';\nimport Logger from '../Logger';\nimport type {\n  AgentType,\n  GetUrlProxyMethodType,\n  IsProxyConfiguredMethodType,\n  MustUrlUseProxyMethodType,\n  ProtocolType,\n} from '../types';\n\nconst log = Logger.child({\n  namespace: 'Agent',\n});\n\nlet requestId = 0;\n\nclass Agent {\n  defaultPort: number;\n\n  protocol: ProtocolType;\n\n  fallbackAgent: AgentType;\n\n  isProxyConfigured: IsProxyConfiguredMethodType;\n\n  mustUrlUseProxy: MustUrlUseProxyMethodType;\n\n  getUrlProxy: GetUrlProxyMethodType;\n\n  socketConnectionTimeout: number;\n\n  constructor (\n    isProxyConfigured: IsProxyConfiguredMethodType,\n    mustUrlUseProxy: MustUrlUseProxyMethodType,\n    getUrlProxy: GetUrlProxyMethodType,\n    fallbackAgent: AgentType,\n    socketConnectionTimeout: number,\n  ) {\n    this.fallbackAgent = fallbackAgent;\n    this.isProxyConfigured = isProxyConfigured;\n    this.mustUrlUseProxy = mustUrlUseProxy;\n    this.getUrlProxy = getUrlProxy;\n    this.socketConnectionTimeout = socketConnectionTimeout;\n  }\n\n  addRequest (request: *, configuration: *) {\n    let requestUrl;\n\n    // It is possible that addRequest was constructed for a proxied request already, e.g.\n    // \"request\" package does this when it detects that a proxy should be used\n    // https://github.com/request/request/blob/212570b6971a732b8dd9f3c73354bcdda158a737/request.js#L402\n    // https://gist.github.com/gajus/e2074cd3b747864ffeaabbd530d30218\n    if (request.path.startsWith('http://') || request.path.startsWith('https://')) {\n      requestUrl = request.path;\n    } else {\n      requestUrl = this.protocol + '//' + (configuration.hostname || configuration.host) + (configuration.port === 80 || configuration.port === 443 ? '' : ':' + configuration.port) + request.path;\n    }\n\n    if (!this.isProxyConfigured()) {\n      log.trace({\n        destination: requestUrl,\n      }, 'not proxying request; GLOBAL_AGENT.HTTP_PROXY is not configured');\n\n      // $FlowFixMe It appears that Flow is missing the method description.\n      this.fallbackAgent.addRequest(request, configuration);\n\n      return;\n    }\n\n    if (!this.mustUrlUseProxy(requestUrl)) {\n      log.trace({\n        destination: requestUrl,\n      }, 'not proxying request; url matches GLOBAL_AGENT.NO_PROXY');\n\n      // $FlowFixMe It appears that Flow is missing the method description.\n      this.fallbackAgent.addRequest(request, configuration);\n\n      return;\n    }\n\n    const currentRequestId = requestId++;\n\n    const proxy = this.getUrlProxy(requestUrl);\n\n    if (this.protocol === 'http:') {\n      request.path = requestUrl;\n\n      if (proxy.authorization) {\n        request.setHeader('proxy-authorization', 'Basic ' + Buffer.from(proxy.authorization).toString('base64'));\n      }\n    }\n\n    log.trace({\n      destination: requestUrl,\n      proxy: 'http://' + proxy.hostname + ':' + proxy.port,\n      requestId: currentRequestId,\n    }, 'proxying request');\n\n    request.on('error', (error) => {\n      log.error({\n        error: serializeError(error),\n      }, 'request error');\n    });\n\n    request.once('response', (response) => {\n      log.trace({\n        headers: response.headers,\n        requestId: currentRequestId,\n        statusCode: response.statusCode,\n      }, 'proxying response');\n    });\n\n    request.shouldKeepAlive = false;\n\n    const connectionConfiguration = {\n      host: configuration.hostname || configuration.host,\n      port: configuration.port || 80,\n      proxy,\n      tls: {},\n    };\n\n    // add optional tls options for https requests.\n    // @see https://nodejs.org/docs/latest-v12.x/api/https.html#https_https_request_url_options_callback :\n    // > The following additional options from tls.connect()\n    // >   - https://nodejs.org/docs/latest-v12.x/api/tls.html#tls_tls_connect_options_callback -\n    // > are also accepted:\n    // >   ca, cert, ciphers, clientCertEngine, crl, dhparam, ecdhCurve, honorCipherOrder,\n    // >   key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext.\n    if (this.protocol === 'https:') {\n      connectionConfiguration.tls = {\n        ca: configuration.ca,\n        cert: configuration.cert,\n        ciphers: configuration.ciphers,\n        clientCertEngine: configuration.clientCertEngine,\n        crl: configuration.crl,\n        dhparam: configuration.dhparam,\n        ecdhCurve: configuration.ecdhCurve,\n        honorCipherOrder: configuration.honorCipherOrder,\n        key: configuration.key,\n        passphrase: configuration.passphrase,\n        pfx: configuration.pfx,\n        rejectUnauthorized: configuration.rejectUnauthorized,\n        secureOptions: configuration.secureOptions,\n        secureProtocol: configuration.secureProtocol,\n        servername: configuration.servername || connectionConfiguration.host,\n        sessionIdContext: configuration.sessionIdContext,\n      };\n\n      // This is not ideal because there is no way to override this setting using `tls` configuration if `NODE_TLS_REJECT_UNAUTHORIZED=0`.\n      // However, popular HTTP clients (such as https://github.com/sindresorhus/got) come with pre-configured value for `rejectUnauthorized`,\n      // which makes it impossible to override that value globally and respect `rejectUnauthorized` for specific requests only.\n      //\n      // eslint-disable-next-line no-process-env\n      if (typeof process.env.NODE_TLS_REJECT_UNAUTHORIZED === 'string' && boolean(process.env.NODE_TLS_REJECT_UNAUTHORIZED) === false) {\n        connectionConfiguration.tls.rejectUnauthorized = false;\n      }\n    }\n\n    // $FlowFixMe It appears that Flow is missing the method description.\n    this.createConnection(connectionConfiguration, (error, socket) => {\n      log.trace({\n        target: connectionConfiguration,\n      }, 'connecting');\n\n      // @see https://github.com/nodejs/node/issues/5757#issuecomment-305969057\n      if (socket) {\n        socket.setTimeout(this.socketConnectionTimeout, () => {\n          socket.destroy();\n        });\n\n        socket.once('connect', () => {\n          log.trace({\n            target: connectionConfiguration,\n          }, 'connected');\n\n          socket.setTimeout(0);\n        });\n\n        socket.once('secureConnect', () => {\n          log.trace({\n            target: connectionConfiguration,\n          }, 'connected (secure)');\n\n          socket.setTimeout(0);\n        });\n      }\n\n      if (error) {\n        request.emit('error', error);\n      } else {\n        log.debug('created socket');\n\n        socket.on('error', (socketError) => {\n          log.error({\n            error: serializeError(socketError),\n          }, 'socket error');\n        });\n\n        request.onSocket(socket);\n      }\n    });\n  }\n}\n\nexport default Agent;\n"],"file":"Agent.js"}