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