{"version":3,"sources":["../../../src/gateway/http.ts"],"sourcesContent":["import url from 'url'\nimport http from 'http'\nimport https from 'https'\n\nimport { assign } from '../utils/index'\nimport { Gateway } from './gateway'\nimport type { Method, HTTPGatewayConfiguration, HTTPRequestParams } from './types'\nimport Response from '../response'\nimport { createTimeoutError } from './timeout-error'\nimport type { Primitive } from '../types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Chunk = any\n\nexport class HTTP extends Gateway {\n  private canceled = false\n\n  get() {\n    this.performRequest('get')\n  }\n\n  head() {\n    this.performRequest('head')\n  }\n\n  post() {\n    this.performRequest('post')\n  }\n\n  put() {\n    this.performRequest('put')\n  }\n\n  patch() {\n    this.performRequest('patch')\n  }\n\n  delete() {\n    this.performRequest('delete')\n  }\n\n  performRequest(requestMethod: Method) {\n    const headers: Record<string, Primitive> = {}\n    // FIXME: Deprecated API\n    // eslint-disable-next-line n/no-deprecated-api\n    const defaults = url.parse(this.request.url())\n    const method = this.shouldEmulateHTTP() ? 'post' : requestMethod\n    const body = this.prepareBody(requestMethod, headers)\n    const timeout = this.request.timeout()\n    const signal = this.request.signal()\n\n    this.canceled = false\n\n    if (\n      body &&\n      typeof body !== 'boolean' &&\n      typeof body !== 'number' &&\n      typeof body.length === 'number'\n    ) {\n      headers['content-length'] = Buffer.byteLength(body)\n    }\n\n    const handler = defaults.protocol === 'https:' ? https : http\n\n    const requestParams: http.RequestOptions = assign(defaults, {\n      method,\n      headers: assign(headers, this.request.headers() as http.OutgoingHttpHeaders),\n    })\n\n    const auth = this.request.auth()\n    if (auth) {\n      const username = auth.username || ''\n      const password = auth.password || ''\n      requestParams['auth'] = `${username}:${password}`\n    }\n\n    const httpOptions = this.options().HTTP\n\n    if (httpOptions.useSocketConnectionTimeout) {\n      requestParams['timeout'] = timeout\n    }\n\n    if (httpOptions.configure) {\n      assign(requestParams, httpOptions.configure(requestParams))\n    }\n\n    if (httpOptions.onRequestWillStart) {\n      httpOptions.onRequestWillStart(requestParams)\n    }\n\n    if (signal) {\n      requestParams.signal = signal\n    }\n\n    const httpRequest = handler.request(requestParams, (httpResponse) =>\n      this.onResponse(httpResponse, httpOptions, requestParams)\n    )\n\n    httpRequest.on('socket', (socket) => {\n      if (httpOptions.onRequestSocketAssigned) {\n        httpOptions.onRequestSocketAssigned(requestParams)\n      }\n\n      if (httpRequest.reusedSocket) {\n        return\n      }\n\n      if (httpOptions.onSocketLookup) {\n        socket.on('lookup', () => {\n          httpOptions.onSocketLookup?.(requestParams)\n        })\n      }\n      if (httpOptions.onSocketConnect) {\n        socket.on('connect', () => {\n          httpOptions.onSocketConnect?.(requestParams)\n        })\n      }\n      if (httpOptions.onSocketSecureConnect) {\n        socket.on('secureConnect', () => {\n          httpOptions.onSocketSecureConnect?.(requestParams)\n        })\n      }\n    })\n\n    httpRequest.on('error', (e) => this.onError(e))\n    body && httpRequest.write(body)\n\n    if (timeout) {\n      if (!httpOptions.useSocketConnectionTimeout) {\n        httpRequest.setTimeout(timeout)\n      }\n\n      httpRequest.on('timeout', () => {\n        this.canceled = true\n        httpRequest.abort()\n        const error = createTimeoutError(`Timeout (${timeout}ms)`)\n        this.dispatchClientError(error.message, error)\n      })\n    }\n\n    httpRequest.end()\n  }\n\n  onResponse(\n    httpResponse: http.IncomingMessage,\n    httpOptions: Partial<HTTPGatewayConfiguration>,\n    requestParams: HTTPRequestParams\n  ) {\n    const rawData: Chunk[] = []\n\n    if (!this.request.isBinary()) {\n      httpResponse.setEncoding('utf8')\n    }\n\n    httpResponse.once('readable', () => {\n      if (httpOptions.onResponseReadable) {\n        httpOptions.onResponseReadable(requestParams)\n      }\n    })\n\n    httpResponse\n      .on('data', (chunk) => rawData.push(chunk))\n      .on('end', () => {\n        if (this.canceled) {\n          return\n        }\n\n        this.dispatchResponse(this.createResponse(httpResponse, rawData))\n      })\n\n    httpResponse.on('end', () => {\n      if (httpOptions.onResponseEnd) {\n        httpOptions.onResponseEnd(requestParams)\n      }\n    })\n  }\n\n  onError(e: Error) {\n    if (this.canceled) {\n      return\n    }\n\n    this.dispatchClientError(e.message, e)\n  }\n\n  createResponse(httpResponse: http.IncomingMessage, rawData: Chunk) {\n    const responseData = this.request.isBinary() ? Buffer.concat(rawData) : rawData.join('')\n\n    return new Response(\n      this.request,\n      httpResponse.statusCode as number,\n      responseData,\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      httpResponse.headers as any\n    )\n  }\n}\n\nexport default HTTP\n"],"mappings":"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","names":[]}