11cb0ef41Sopenharmony_ci'use strict'
21cb0ef41Sopenharmony_ciconst { URL } = require('url')
31cb0ef41Sopenharmony_ciconst { Minipass } = require('minipass')
41cb0ef41Sopenharmony_ciconst Headers = require('./headers.js')
51cb0ef41Sopenharmony_ciconst { exportNodeCompatibleHeaders } = Headers
61cb0ef41Sopenharmony_ciconst Body = require('./body.js')
71cb0ef41Sopenharmony_ciconst { clone, extractContentType, getTotalBytes } = Body
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst version = require('../package.json').version
101cb0ef41Sopenharmony_ciconst defaultUserAgent =
111cb0ef41Sopenharmony_ci  `minipass-fetch/${version} (+https://github.com/isaacs/minipass-fetch)`
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciconst INTERNALS = Symbol('Request internals')
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst isRequest = input =>
161cb0ef41Sopenharmony_ci  typeof input === 'object' && typeof input[INTERNALS] === 'object'
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst isAbortSignal = signal => {
191cb0ef41Sopenharmony_ci  const proto = (
201cb0ef41Sopenharmony_ci    signal
211cb0ef41Sopenharmony_ci    && typeof signal === 'object'
221cb0ef41Sopenharmony_ci    && Object.getPrototypeOf(signal)
231cb0ef41Sopenharmony_ci  )
241cb0ef41Sopenharmony_ci  return !!(proto && proto.constructor.name === 'AbortSignal')
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciclass Request extends Body {
281cb0ef41Sopenharmony_ci  constructor (input, init = {}) {
291cb0ef41Sopenharmony_ci    const parsedURL = isRequest(input) ? new URL(input.url)
301cb0ef41Sopenharmony_ci      : input && input.href ? new URL(input.href)
311cb0ef41Sopenharmony_ci      : new URL(`${input}`)
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    if (isRequest(input)) {
341cb0ef41Sopenharmony_ci      init = { ...input[INTERNALS], ...init }
351cb0ef41Sopenharmony_ci    } else if (!input || typeof input === 'string') {
361cb0ef41Sopenharmony_ci      input = {}
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci    const method = (init.method || input.method || 'GET').toUpperCase()
401cb0ef41Sopenharmony_ci    const isGETHEAD = method === 'GET' || method === 'HEAD'
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci    if ((init.body !== null && init.body !== undefined ||
431cb0ef41Sopenharmony_ci        isRequest(input) && input.body !== null) && isGETHEAD) {
441cb0ef41Sopenharmony_ci      throw new TypeError('Request with GET/HEAD method cannot have body')
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci    const inputBody = init.body !== null && init.body !== undefined ? init.body
481cb0ef41Sopenharmony_ci      : isRequest(input) && input.body !== null ? clone(input)
491cb0ef41Sopenharmony_ci      : null
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    super(inputBody, {
521cb0ef41Sopenharmony_ci      timeout: init.timeout || input.timeout || 0,
531cb0ef41Sopenharmony_ci      size: init.size || input.size || 0,
541cb0ef41Sopenharmony_ci    })
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    const headers = new Headers(init.headers || input.headers || {})
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    if (inputBody !== null && inputBody !== undefined &&
591cb0ef41Sopenharmony_ci        !headers.has('Content-Type')) {
601cb0ef41Sopenharmony_ci      const contentType = extractContentType(inputBody)
611cb0ef41Sopenharmony_ci      if (contentType) {
621cb0ef41Sopenharmony_ci        headers.append('Content-Type', contentType)
631cb0ef41Sopenharmony_ci      }
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    const signal = 'signal' in init ? init.signal
671cb0ef41Sopenharmony_ci      : null
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci    if (signal !== null && signal !== undefined && !isAbortSignal(signal)) {
701cb0ef41Sopenharmony_ci      throw new TypeError('Expected signal must be an instanceof AbortSignal')
711cb0ef41Sopenharmony_ci    }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci    // TLS specific options that are handled by node
741cb0ef41Sopenharmony_ci    const {
751cb0ef41Sopenharmony_ci      ca,
761cb0ef41Sopenharmony_ci      cert,
771cb0ef41Sopenharmony_ci      ciphers,
781cb0ef41Sopenharmony_ci      clientCertEngine,
791cb0ef41Sopenharmony_ci      crl,
801cb0ef41Sopenharmony_ci      dhparam,
811cb0ef41Sopenharmony_ci      ecdhCurve,
821cb0ef41Sopenharmony_ci      family,
831cb0ef41Sopenharmony_ci      honorCipherOrder,
841cb0ef41Sopenharmony_ci      key,
851cb0ef41Sopenharmony_ci      passphrase,
861cb0ef41Sopenharmony_ci      pfx,
871cb0ef41Sopenharmony_ci      rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0',
881cb0ef41Sopenharmony_ci      secureOptions,
891cb0ef41Sopenharmony_ci      secureProtocol,
901cb0ef41Sopenharmony_ci      servername,
911cb0ef41Sopenharmony_ci      sessionIdContext,
921cb0ef41Sopenharmony_ci    } = init
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci    this[INTERNALS] = {
951cb0ef41Sopenharmony_ci      method,
961cb0ef41Sopenharmony_ci      redirect: init.redirect || input.redirect || 'follow',
971cb0ef41Sopenharmony_ci      headers,
981cb0ef41Sopenharmony_ci      parsedURL,
991cb0ef41Sopenharmony_ci      signal,
1001cb0ef41Sopenharmony_ci      ca,
1011cb0ef41Sopenharmony_ci      cert,
1021cb0ef41Sopenharmony_ci      ciphers,
1031cb0ef41Sopenharmony_ci      clientCertEngine,
1041cb0ef41Sopenharmony_ci      crl,
1051cb0ef41Sopenharmony_ci      dhparam,
1061cb0ef41Sopenharmony_ci      ecdhCurve,
1071cb0ef41Sopenharmony_ci      family,
1081cb0ef41Sopenharmony_ci      honorCipherOrder,
1091cb0ef41Sopenharmony_ci      key,
1101cb0ef41Sopenharmony_ci      passphrase,
1111cb0ef41Sopenharmony_ci      pfx,
1121cb0ef41Sopenharmony_ci      rejectUnauthorized,
1131cb0ef41Sopenharmony_ci      secureOptions,
1141cb0ef41Sopenharmony_ci      secureProtocol,
1151cb0ef41Sopenharmony_ci      servername,
1161cb0ef41Sopenharmony_ci      sessionIdContext,
1171cb0ef41Sopenharmony_ci    }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci    // node-fetch-only options
1201cb0ef41Sopenharmony_ci    this.follow = init.follow !== undefined ? init.follow
1211cb0ef41Sopenharmony_ci      : input.follow !== undefined ? input.follow
1221cb0ef41Sopenharmony_ci      : 20
1231cb0ef41Sopenharmony_ci    this.compress = init.compress !== undefined ? init.compress
1241cb0ef41Sopenharmony_ci      : input.compress !== undefined ? input.compress
1251cb0ef41Sopenharmony_ci      : true
1261cb0ef41Sopenharmony_ci    this.counter = init.counter || input.counter || 0
1271cb0ef41Sopenharmony_ci    this.agent = init.agent || input.agent
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  get method () {
1311cb0ef41Sopenharmony_ci    return this[INTERNALS].method
1321cb0ef41Sopenharmony_ci  }
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  get url () {
1351cb0ef41Sopenharmony_ci    return this[INTERNALS].parsedURL.toString()
1361cb0ef41Sopenharmony_ci  }
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_ci  get headers () {
1391cb0ef41Sopenharmony_ci    return this[INTERNALS].headers
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  get redirect () {
1431cb0ef41Sopenharmony_ci    return this[INTERNALS].redirect
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  get signal () {
1471cb0ef41Sopenharmony_ci    return this[INTERNALS].signal
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  clone () {
1511cb0ef41Sopenharmony_ci    return new Request(this)
1521cb0ef41Sopenharmony_ci  }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  get [Symbol.toStringTag] () {
1551cb0ef41Sopenharmony_ci    return 'Request'
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  static getNodeRequestOptions (request) {
1591cb0ef41Sopenharmony_ci    const parsedURL = request[INTERNALS].parsedURL
1601cb0ef41Sopenharmony_ci    const headers = new Headers(request[INTERNALS].headers)
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci    // fetch step 1.3
1631cb0ef41Sopenharmony_ci    if (!headers.has('Accept')) {
1641cb0ef41Sopenharmony_ci      headers.set('Accept', '*/*')
1651cb0ef41Sopenharmony_ci    }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci    // Basic fetch
1681cb0ef41Sopenharmony_ci    if (!/^https?:$/.test(parsedURL.protocol)) {
1691cb0ef41Sopenharmony_ci      throw new TypeError('Only HTTP(S) protocols are supported')
1701cb0ef41Sopenharmony_ci    }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci    if (request.signal &&
1731cb0ef41Sopenharmony_ci        Minipass.isStream(request.body) &&
1741cb0ef41Sopenharmony_ci        typeof request.body.destroy !== 'function') {
1751cb0ef41Sopenharmony_ci      throw new Error(
1761cb0ef41Sopenharmony_ci        'Cancellation of streamed requests with AbortSignal is not supported')
1771cb0ef41Sopenharmony_ci    }
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci    // HTTP-network-or-cache fetch steps 2.4-2.7
1801cb0ef41Sopenharmony_ci    const contentLengthValue =
1811cb0ef41Sopenharmony_ci      (request.body === null || request.body === undefined) &&
1821cb0ef41Sopenharmony_ci        /^(POST|PUT)$/i.test(request.method) ? '0'
1831cb0ef41Sopenharmony_ci      : request.body !== null && request.body !== undefined
1841cb0ef41Sopenharmony_ci        ? getTotalBytes(request)
1851cb0ef41Sopenharmony_ci        : null
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci    if (contentLengthValue) {
1881cb0ef41Sopenharmony_ci      headers.set('Content-Length', contentLengthValue + '')
1891cb0ef41Sopenharmony_ci    }
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ci    // HTTP-network-or-cache fetch step 2.11
1921cb0ef41Sopenharmony_ci    if (!headers.has('User-Agent')) {
1931cb0ef41Sopenharmony_ci      headers.set('User-Agent', defaultUserAgent)
1941cb0ef41Sopenharmony_ci    }
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci    // HTTP-network-or-cache fetch step 2.15
1971cb0ef41Sopenharmony_ci    if (request.compress && !headers.has('Accept-Encoding')) {
1981cb0ef41Sopenharmony_ci      headers.set('Accept-Encoding', 'gzip,deflate')
1991cb0ef41Sopenharmony_ci    }
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci    const agent = typeof request.agent === 'function'
2021cb0ef41Sopenharmony_ci      ? request.agent(parsedURL)
2031cb0ef41Sopenharmony_ci      : request.agent
2041cb0ef41Sopenharmony_ci
2051cb0ef41Sopenharmony_ci    if (!headers.has('Connection') && !agent) {
2061cb0ef41Sopenharmony_ci      headers.set('Connection', 'close')
2071cb0ef41Sopenharmony_ci    }
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci    // TLS specific options that are handled by node
2101cb0ef41Sopenharmony_ci    const {
2111cb0ef41Sopenharmony_ci      ca,
2121cb0ef41Sopenharmony_ci      cert,
2131cb0ef41Sopenharmony_ci      ciphers,
2141cb0ef41Sopenharmony_ci      clientCertEngine,
2151cb0ef41Sopenharmony_ci      crl,
2161cb0ef41Sopenharmony_ci      dhparam,
2171cb0ef41Sopenharmony_ci      ecdhCurve,
2181cb0ef41Sopenharmony_ci      family,
2191cb0ef41Sopenharmony_ci      honorCipherOrder,
2201cb0ef41Sopenharmony_ci      key,
2211cb0ef41Sopenharmony_ci      passphrase,
2221cb0ef41Sopenharmony_ci      pfx,
2231cb0ef41Sopenharmony_ci      rejectUnauthorized,
2241cb0ef41Sopenharmony_ci      secureOptions,
2251cb0ef41Sopenharmony_ci      secureProtocol,
2261cb0ef41Sopenharmony_ci      servername,
2271cb0ef41Sopenharmony_ci      sessionIdContext,
2281cb0ef41Sopenharmony_ci    } = request[INTERNALS]
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci    // HTTP-network fetch step 4.2
2311cb0ef41Sopenharmony_ci    // chunked encoding is handled by Node.js
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ci    // we cannot spread parsedURL directly, so we have to read each property one-by-one
2341cb0ef41Sopenharmony_ci    // and map them to the equivalent https?.request() method options
2351cb0ef41Sopenharmony_ci    const urlProps = {
2361cb0ef41Sopenharmony_ci      auth: parsedURL.username || parsedURL.password
2371cb0ef41Sopenharmony_ci        ? `${parsedURL.username}:${parsedURL.password}`
2381cb0ef41Sopenharmony_ci        : '',
2391cb0ef41Sopenharmony_ci      host: parsedURL.host,
2401cb0ef41Sopenharmony_ci      hostname: parsedURL.hostname,
2411cb0ef41Sopenharmony_ci      path: `${parsedURL.pathname}${parsedURL.search}`,
2421cb0ef41Sopenharmony_ci      port: parsedURL.port,
2431cb0ef41Sopenharmony_ci      protocol: parsedURL.protocol,
2441cb0ef41Sopenharmony_ci    }
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci    return {
2471cb0ef41Sopenharmony_ci      ...urlProps,
2481cb0ef41Sopenharmony_ci      method: request.method,
2491cb0ef41Sopenharmony_ci      headers: exportNodeCompatibleHeaders(headers),
2501cb0ef41Sopenharmony_ci      agent,
2511cb0ef41Sopenharmony_ci      ca,
2521cb0ef41Sopenharmony_ci      cert,
2531cb0ef41Sopenharmony_ci      ciphers,
2541cb0ef41Sopenharmony_ci      clientCertEngine,
2551cb0ef41Sopenharmony_ci      crl,
2561cb0ef41Sopenharmony_ci      dhparam,
2571cb0ef41Sopenharmony_ci      ecdhCurve,
2581cb0ef41Sopenharmony_ci      family,
2591cb0ef41Sopenharmony_ci      honorCipherOrder,
2601cb0ef41Sopenharmony_ci      key,
2611cb0ef41Sopenharmony_ci      passphrase,
2621cb0ef41Sopenharmony_ci      pfx,
2631cb0ef41Sopenharmony_ci      rejectUnauthorized,
2641cb0ef41Sopenharmony_ci      secureOptions,
2651cb0ef41Sopenharmony_ci      secureProtocol,
2661cb0ef41Sopenharmony_ci      servername,
2671cb0ef41Sopenharmony_ci      sessionIdContext,
2681cb0ef41Sopenharmony_ci      timeout: request.timeout,
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci}
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_cimodule.exports = Request
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ciObject.defineProperties(Request.prototype, {
2761cb0ef41Sopenharmony_ci  method: { enumerable: true },
2771cb0ef41Sopenharmony_ci  url: { enumerable: true },
2781cb0ef41Sopenharmony_ci  headers: { enumerable: true },
2791cb0ef41Sopenharmony_ci  redirect: { enumerable: true },
2801cb0ef41Sopenharmony_ci  clone: { enumerable: true },
2811cb0ef41Sopenharmony_ci  signal: { enumerable: true },
2821cb0ef41Sopenharmony_ci})
283