11cb0ef41Sopenharmony_ci/* globals AbortController */ 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci'use strict' 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciconst { extractBody, mixinBody, cloneBody } = require('./body') 61cb0ef41Sopenharmony_ciconst { Headers, fill: fillHeaders, HeadersList } = require('./headers') 71cb0ef41Sopenharmony_ciconst { FinalizationRegistry } = require('../compat/dispatcher-weakref')() 81cb0ef41Sopenharmony_ciconst util = require('../core/util') 91cb0ef41Sopenharmony_ciconst { 101cb0ef41Sopenharmony_ci isValidHTTPToken, 111cb0ef41Sopenharmony_ci sameOrigin, 121cb0ef41Sopenharmony_ci normalizeMethod, 131cb0ef41Sopenharmony_ci makePolicyContainer, 141cb0ef41Sopenharmony_ci normalizeMethodRecord 151cb0ef41Sopenharmony_ci} = require('./util') 161cb0ef41Sopenharmony_ciconst { 171cb0ef41Sopenharmony_ci forbiddenMethodsSet, 181cb0ef41Sopenharmony_ci corsSafeListedMethodsSet, 191cb0ef41Sopenharmony_ci referrerPolicy, 201cb0ef41Sopenharmony_ci requestRedirect, 211cb0ef41Sopenharmony_ci requestMode, 221cb0ef41Sopenharmony_ci requestCredentials, 231cb0ef41Sopenharmony_ci requestCache, 241cb0ef41Sopenharmony_ci requestDuplex 251cb0ef41Sopenharmony_ci} = require('./constants') 261cb0ef41Sopenharmony_ciconst { kEnumerableProperty } = util 271cb0ef41Sopenharmony_ciconst { kHeaders, kSignal, kState, kGuard, kRealm } = require('./symbols') 281cb0ef41Sopenharmony_ciconst { webidl } = require('./webidl') 291cb0ef41Sopenharmony_ciconst { getGlobalOrigin } = require('./global') 301cb0ef41Sopenharmony_ciconst { URLSerializer } = require('./dataURL') 311cb0ef41Sopenharmony_ciconst { kHeadersList, kConstruct } = require('../core/symbols') 321cb0ef41Sopenharmony_ciconst assert = require('assert') 331cb0ef41Sopenharmony_ciconst { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = require('events') 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cilet TransformStream = globalThis.TransformStream 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ciconst kAbortController = Symbol('abortController') 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciconst requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { 401cb0ef41Sopenharmony_ci signal.removeEventListener('abort', abort) 411cb0ef41Sopenharmony_ci}) 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// https://fetch.spec.whatwg.org/#request-class 441cb0ef41Sopenharmony_ciclass Request { 451cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#dom-request 461cb0ef41Sopenharmony_ci constructor (input, init = {}) { 471cb0ef41Sopenharmony_ci if (input === kConstruct) { 481cb0ef41Sopenharmony_ci return 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci input = webidl.converters.RequestInfo(input) 541cb0ef41Sopenharmony_ci init = webidl.converters.RequestInit(init) 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object 571cb0ef41Sopenharmony_ci this[kRealm] = { 581cb0ef41Sopenharmony_ci settingsObject: { 591cb0ef41Sopenharmony_ci baseUrl: getGlobalOrigin(), 601cb0ef41Sopenharmony_ci get origin () { 611cb0ef41Sopenharmony_ci return this.baseUrl?.origin 621cb0ef41Sopenharmony_ci }, 631cb0ef41Sopenharmony_ci policyContainer: makePolicyContainer() 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci // 1. Let request be null. 681cb0ef41Sopenharmony_ci let request = null 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci // 2. Let fallbackMode be null. 711cb0ef41Sopenharmony_ci let fallbackMode = null 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci // 3. Let baseURL be this’s relevant settings object’s API base URL. 741cb0ef41Sopenharmony_ci const baseUrl = this[kRealm].settingsObject.baseUrl 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // 4. Let signal be null. 771cb0ef41Sopenharmony_ci let signal = null 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // 5. If input is a string, then: 801cb0ef41Sopenharmony_ci if (typeof input === 'string') { 811cb0ef41Sopenharmony_ci // 1. Let parsedURL be the result of parsing input with baseURL. 821cb0ef41Sopenharmony_ci // 2. If parsedURL is failure, then throw a TypeError. 831cb0ef41Sopenharmony_ci let parsedURL 841cb0ef41Sopenharmony_ci try { 851cb0ef41Sopenharmony_ci parsedURL = new URL(input, baseUrl) 861cb0ef41Sopenharmony_ci } catch (err) { 871cb0ef41Sopenharmony_ci throw new TypeError('Failed to parse URL from ' + input, { cause: err }) 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci // 3. If parsedURL includes credentials, then throw a TypeError. 911cb0ef41Sopenharmony_ci if (parsedURL.username || parsedURL.password) { 921cb0ef41Sopenharmony_ci throw new TypeError( 931cb0ef41Sopenharmony_ci 'Request cannot be constructed from a URL that includes credentials: ' + 941cb0ef41Sopenharmony_ci input 951cb0ef41Sopenharmony_ci ) 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci // 4. Set request to a new request whose URL is parsedURL. 991cb0ef41Sopenharmony_ci request = makeRequest({ urlList: [parsedURL] }) 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // 5. Set fallbackMode to "cors". 1021cb0ef41Sopenharmony_ci fallbackMode = 'cors' 1031cb0ef41Sopenharmony_ci } else { 1041cb0ef41Sopenharmony_ci // 6. Otherwise: 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci // 7. Assert: input is a Request object. 1071cb0ef41Sopenharmony_ci assert(input instanceof Request) 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci // 8. Set request to input’s request. 1101cb0ef41Sopenharmony_ci request = input[kState] 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // 9. Set signal to input’s signal. 1131cb0ef41Sopenharmony_ci signal = input[kSignal] 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci // 7. Let origin be this’s relevant settings object’s origin. 1171cb0ef41Sopenharmony_ci const origin = this[kRealm].settingsObject.origin 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci // 8. Let window be "client". 1201cb0ef41Sopenharmony_ci let window = 'client' 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci // 9. If request’s window is an environment settings object and its origin 1231cb0ef41Sopenharmony_ci // is same origin with origin, then set window to request’s window. 1241cb0ef41Sopenharmony_ci if ( 1251cb0ef41Sopenharmony_ci request.window?.constructor?.name === 'EnvironmentSettingsObject' && 1261cb0ef41Sopenharmony_ci sameOrigin(request.window, origin) 1271cb0ef41Sopenharmony_ci ) { 1281cb0ef41Sopenharmony_ci window = request.window 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // 10. If init["window"] exists and is non-null, then throw a TypeError. 1321cb0ef41Sopenharmony_ci if (init.window != null) { 1331cb0ef41Sopenharmony_ci throw new TypeError(`'window' option '${window}' must be null`) 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci // 11. If init["window"] exists, then set window to "no-window". 1371cb0ef41Sopenharmony_ci if ('window' in init) { 1381cb0ef41Sopenharmony_ci window = 'no-window' 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci // 12. Set request to a new request with the following properties: 1421cb0ef41Sopenharmony_ci request = makeRequest({ 1431cb0ef41Sopenharmony_ci // URL request’s URL. 1441cb0ef41Sopenharmony_ci // undici implementation note: this is set as the first item in request's urlList in makeRequest 1451cb0ef41Sopenharmony_ci // method request’s method. 1461cb0ef41Sopenharmony_ci method: request.method, 1471cb0ef41Sopenharmony_ci // header list A copy of request’s header list. 1481cb0ef41Sopenharmony_ci // undici implementation note: headersList is cloned in makeRequest 1491cb0ef41Sopenharmony_ci headersList: request.headersList, 1501cb0ef41Sopenharmony_ci // unsafe-request flag Set. 1511cb0ef41Sopenharmony_ci unsafeRequest: request.unsafeRequest, 1521cb0ef41Sopenharmony_ci // client This’s relevant settings object. 1531cb0ef41Sopenharmony_ci client: this[kRealm].settingsObject, 1541cb0ef41Sopenharmony_ci // window window. 1551cb0ef41Sopenharmony_ci window, 1561cb0ef41Sopenharmony_ci // priority request’s priority. 1571cb0ef41Sopenharmony_ci priority: request.priority, 1581cb0ef41Sopenharmony_ci // origin request’s origin. The propagation of the origin is only significant for navigation requests 1591cb0ef41Sopenharmony_ci // being handled by a service worker. In this scenario a request can have an origin that is different 1601cb0ef41Sopenharmony_ci // from the current client. 1611cb0ef41Sopenharmony_ci origin: request.origin, 1621cb0ef41Sopenharmony_ci // referrer request’s referrer. 1631cb0ef41Sopenharmony_ci referrer: request.referrer, 1641cb0ef41Sopenharmony_ci // referrer policy request’s referrer policy. 1651cb0ef41Sopenharmony_ci referrerPolicy: request.referrerPolicy, 1661cb0ef41Sopenharmony_ci // mode request’s mode. 1671cb0ef41Sopenharmony_ci mode: request.mode, 1681cb0ef41Sopenharmony_ci // credentials mode request’s credentials mode. 1691cb0ef41Sopenharmony_ci credentials: request.credentials, 1701cb0ef41Sopenharmony_ci // cache mode request’s cache mode. 1711cb0ef41Sopenharmony_ci cache: request.cache, 1721cb0ef41Sopenharmony_ci // redirect mode request’s redirect mode. 1731cb0ef41Sopenharmony_ci redirect: request.redirect, 1741cb0ef41Sopenharmony_ci // integrity metadata request’s integrity metadata. 1751cb0ef41Sopenharmony_ci integrity: request.integrity, 1761cb0ef41Sopenharmony_ci // keepalive request’s keepalive. 1771cb0ef41Sopenharmony_ci keepalive: request.keepalive, 1781cb0ef41Sopenharmony_ci // reload-navigation flag request’s reload-navigation flag. 1791cb0ef41Sopenharmony_ci reloadNavigation: request.reloadNavigation, 1801cb0ef41Sopenharmony_ci // history-navigation flag request’s history-navigation flag. 1811cb0ef41Sopenharmony_ci historyNavigation: request.historyNavigation, 1821cb0ef41Sopenharmony_ci // URL list A clone of request’s URL list. 1831cb0ef41Sopenharmony_ci urlList: [...request.urlList] 1841cb0ef41Sopenharmony_ci }) 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci const initHasKey = Object.keys(init).length !== 0 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci // 13. If init is not empty, then: 1891cb0ef41Sopenharmony_ci if (initHasKey) { 1901cb0ef41Sopenharmony_ci // 1. If request’s mode is "navigate", then set it to "same-origin". 1911cb0ef41Sopenharmony_ci if (request.mode === 'navigate') { 1921cb0ef41Sopenharmony_ci request.mode = 'same-origin' 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci // 2. Unset request’s reload-navigation flag. 1961cb0ef41Sopenharmony_ci request.reloadNavigation = false 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci // 3. Unset request’s history-navigation flag. 1991cb0ef41Sopenharmony_ci request.historyNavigation = false 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci // 4. Set request’s origin to "client". 2021cb0ef41Sopenharmony_ci request.origin = 'client' 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci // 5. Set request’s referrer to "client" 2051cb0ef41Sopenharmony_ci request.referrer = 'client' 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci // 6. Set request’s referrer policy to the empty string. 2081cb0ef41Sopenharmony_ci request.referrerPolicy = '' 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci // 7. Set request’s URL to request’s current URL. 2111cb0ef41Sopenharmony_ci request.url = request.urlList[request.urlList.length - 1] 2121cb0ef41Sopenharmony_ci 2131cb0ef41Sopenharmony_ci // 8. Set request’s URL list to « request’s URL ». 2141cb0ef41Sopenharmony_ci request.urlList = [request.url] 2151cb0ef41Sopenharmony_ci } 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci // 14. If init["referrer"] exists, then: 2181cb0ef41Sopenharmony_ci if (init.referrer !== undefined) { 2191cb0ef41Sopenharmony_ci // 1. Let referrer be init["referrer"]. 2201cb0ef41Sopenharmony_ci const referrer = init.referrer 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". 2231cb0ef41Sopenharmony_ci if (referrer === '') { 2241cb0ef41Sopenharmony_ci request.referrer = 'no-referrer' 2251cb0ef41Sopenharmony_ci } else { 2261cb0ef41Sopenharmony_ci // 1. Let parsedReferrer be the result of parsing referrer with 2271cb0ef41Sopenharmony_ci // baseURL. 2281cb0ef41Sopenharmony_ci // 2. If parsedReferrer is failure, then throw a TypeError. 2291cb0ef41Sopenharmony_ci let parsedReferrer 2301cb0ef41Sopenharmony_ci try { 2311cb0ef41Sopenharmony_ci parsedReferrer = new URL(referrer, baseUrl) 2321cb0ef41Sopenharmony_ci } catch (err) { 2331cb0ef41Sopenharmony_ci throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci // 3. If one of the following is true 2371cb0ef41Sopenharmony_ci // - parsedReferrer’s scheme is "about" and path is the string "client" 2381cb0ef41Sopenharmony_ci // - parsedReferrer’s origin is not same origin with origin 2391cb0ef41Sopenharmony_ci // then set request’s referrer to "client". 2401cb0ef41Sopenharmony_ci if ( 2411cb0ef41Sopenharmony_ci (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || 2421cb0ef41Sopenharmony_ci (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) 2431cb0ef41Sopenharmony_ci ) { 2441cb0ef41Sopenharmony_ci request.referrer = 'client' 2451cb0ef41Sopenharmony_ci } else { 2461cb0ef41Sopenharmony_ci // 4. Otherwise, set request’s referrer to parsedReferrer. 2471cb0ef41Sopenharmony_ci request.referrer = parsedReferrer 2481cb0ef41Sopenharmony_ci } 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci } 2511cb0ef41Sopenharmony_ci 2521cb0ef41Sopenharmony_ci // 15. If init["referrerPolicy"] exists, then set request’s referrer policy 2531cb0ef41Sopenharmony_ci // to it. 2541cb0ef41Sopenharmony_ci if (init.referrerPolicy !== undefined) { 2551cb0ef41Sopenharmony_ci request.referrerPolicy = init.referrerPolicy 2561cb0ef41Sopenharmony_ci } 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. 2591cb0ef41Sopenharmony_ci let mode 2601cb0ef41Sopenharmony_ci if (init.mode !== undefined) { 2611cb0ef41Sopenharmony_ci mode = init.mode 2621cb0ef41Sopenharmony_ci } else { 2631cb0ef41Sopenharmony_ci mode = fallbackMode 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci // 17. If mode is "navigate", then throw a TypeError. 2671cb0ef41Sopenharmony_ci if (mode === 'navigate') { 2681cb0ef41Sopenharmony_ci throw webidl.errors.exception({ 2691cb0ef41Sopenharmony_ci header: 'Request constructor', 2701cb0ef41Sopenharmony_ci message: 'invalid request mode navigate.' 2711cb0ef41Sopenharmony_ci }) 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci // 18. If mode is non-null, set request’s mode to mode. 2751cb0ef41Sopenharmony_ci if (mode != null) { 2761cb0ef41Sopenharmony_ci request.mode = mode 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci // 19. If init["credentials"] exists, then set request’s credentials mode 2801cb0ef41Sopenharmony_ci // to it. 2811cb0ef41Sopenharmony_ci if (init.credentials !== undefined) { 2821cb0ef41Sopenharmony_ci request.credentials = init.credentials 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ci // 18. If init["cache"] exists, then set request’s cache mode to it. 2861cb0ef41Sopenharmony_ci if (init.cache !== undefined) { 2871cb0ef41Sopenharmony_ci request.cache = init.cache 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci // 21. If request’s cache mode is "only-if-cached" and request’s mode is 2911cb0ef41Sopenharmony_ci // not "same-origin", then throw a TypeError. 2921cb0ef41Sopenharmony_ci if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { 2931cb0ef41Sopenharmony_ci throw new TypeError( 2941cb0ef41Sopenharmony_ci "'only-if-cached' can be set only with 'same-origin' mode" 2951cb0ef41Sopenharmony_ci ) 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci // 22. If init["redirect"] exists, then set request’s redirect mode to it. 2991cb0ef41Sopenharmony_ci if (init.redirect !== undefined) { 3001cb0ef41Sopenharmony_ci request.redirect = init.redirect 3011cb0ef41Sopenharmony_ci } 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci // 23. If init["integrity"] exists, then set request’s integrity metadata to it. 3041cb0ef41Sopenharmony_ci if (init.integrity != null) { 3051cb0ef41Sopenharmony_ci request.integrity = String(init.integrity) 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci // 24. If init["keepalive"] exists, then set request’s keepalive to it. 3091cb0ef41Sopenharmony_ci if (init.keepalive !== undefined) { 3101cb0ef41Sopenharmony_ci request.keepalive = Boolean(init.keepalive) 3111cb0ef41Sopenharmony_ci } 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci // 25. If init["method"] exists, then: 3141cb0ef41Sopenharmony_ci if (init.method !== undefined) { 3151cb0ef41Sopenharmony_ci // 1. Let method be init["method"]. 3161cb0ef41Sopenharmony_ci let method = init.method 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ci // 2. If method is not a method or method is a forbidden method, then 3191cb0ef41Sopenharmony_ci // throw a TypeError. 3201cb0ef41Sopenharmony_ci if (!isValidHTTPToken(method)) { 3211cb0ef41Sopenharmony_ci throw new TypeError(`'${method}' is not a valid HTTP method.`) 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci if (forbiddenMethodsSet.has(method.toUpperCase())) { 3251cb0ef41Sopenharmony_ci throw new TypeError(`'${method}' HTTP method is unsupported.`) 3261cb0ef41Sopenharmony_ci } 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci // 3. Normalize method. 3291cb0ef41Sopenharmony_ci method = normalizeMethodRecord[method] ?? normalizeMethod(method) 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci // 4. Set request’s method to method. 3321cb0ef41Sopenharmony_ci request.method = method 3331cb0ef41Sopenharmony_ci } 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci // 26. If init["signal"] exists, then set signal to it. 3361cb0ef41Sopenharmony_ci if (init.signal !== undefined) { 3371cb0ef41Sopenharmony_ci signal = init.signal 3381cb0ef41Sopenharmony_ci } 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci // 27. Set this’s request to request. 3411cb0ef41Sopenharmony_ci this[kState] = request 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci // 28. Set this’s signal to a new AbortSignal object with this’s relevant 3441cb0ef41Sopenharmony_ci // Realm. 3451cb0ef41Sopenharmony_ci // TODO: could this be simplified with AbortSignal.any 3461cb0ef41Sopenharmony_ci // (https://dom.spec.whatwg.org/#dom-abortsignal-any) 3471cb0ef41Sopenharmony_ci const ac = new AbortController() 3481cb0ef41Sopenharmony_ci this[kSignal] = ac.signal 3491cb0ef41Sopenharmony_ci this[kSignal][kRealm] = this[kRealm] 3501cb0ef41Sopenharmony_ci 3511cb0ef41Sopenharmony_ci // 29. If signal is not null, then make this’s signal follow signal. 3521cb0ef41Sopenharmony_ci if (signal != null) { 3531cb0ef41Sopenharmony_ci if ( 3541cb0ef41Sopenharmony_ci !signal || 3551cb0ef41Sopenharmony_ci typeof signal.aborted !== 'boolean' || 3561cb0ef41Sopenharmony_ci typeof signal.addEventListener !== 'function' 3571cb0ef41Sopenharmony_ci ) { 3581cb0ef41Sopenharmony_ci throw new TypeError( 3591cb0ef41Sopenharmony_ci "Failed to construct 'Request': member signal is not of type AbortSignal." 3601cb0ef41Sopenharmony_ci ) 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci if (signal.aborted) { 3641cb0ef41Sopenharmony_ci ac.abort(signal.reason) 3651cb0ef41Sopenharmony_ci } else { 3661cb0ef41Sopenharmony_ci // Keep a strong ref to ac while request object 3671cb0ef41Sopenharmony_ci // is alive. This is needed to prevent AbortController 3681cb0ef41Sopenharmony_ci // from being prematurely garbage collected. 3691cb0ef41Sopenharmony_ci // See, https://github.com/nodejs/undici/issues/1926. 3701cb0ef41Sopenharmony_ci this[kAbortController] = ac 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci const acRef = new WeakRef(ac) 3731cb0ef41Sopenharmony_ci const abort = function () { 3741cb0ef41Sopenharmony_ci const ac = acRef.deref() 3751cb0ef41Sopenharmony_ci if (ac !== undefined) { 3761cb0ef41Sopenharmony_ci ac.abort(this.reason) 3771cb0ef41Sopenharmony_ci } 3781cb0ef41Sopenharmony_ci } 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci // Third-party AbortControllers may not work with these. 3811cb0ef41Sopenharmony_ci // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. 3821cb0ef41Sopenharmony_ci try { 3831cb0ef41Sopenharmony_ci // If the max amount of listeners is equal to the default, increase it 3841cb0ef41Sopenharmony_ci // This is only available in node >= v19.9.0 3851cb0ef41Sopenharmony_ci if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { 3861cb0ef41Sopenharmony_ci setMaxListeners(100, signal) 3871cb0ef41Sopenharmony_ci } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { 3881cb0ef41Sopenharmony_ci setMaxListeners(100, signal) 3891cb0ef41Sopenharmony_ci } 3901cb0ef41Sopenharmony_ci } catch {} 3911cb0ef41Sopenharmony_ci 3921cb0ef41Sopenharmony_ci util.addAbortListener(signal, abort) 3931cb0ef41Sopenharmony_ci requestFinalizer.register(ac, { signal, abort }) 3941cb0ef41Sopenharmony_ci } 3951cb0ef41Sopenharmony_ci } 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci // 30. Set this’s headers to a new Headers object with this’s relevant 3981cb0ef41Sopenharmony_ci // Realm, whose header list is request’s header list and guard is 3991cb0ef41Sopenharmony_ci // "request". 4001cb0ef41Sopenharmony_ci this[kHeaders] = new Headers(kConstruct) 4011cb0ef41Sopenharmony_ci this[kHeaders][kHeadersList] = request.headersList 4021cb0ef41Sopenharmony_ci this[kHeaders][kGuard] = 'request' 4031cb0ef41Sopenharmony_ci this[kHeaders][kRealm] = this[kRealm] 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ci // 31. If this’s request’s mode is "no-cors", then: 4061cb0ef41Sopenharmony_ci if (mode === 'no-cors') { 4071cb0ef41Sopenharmony_ci // 1. If this’s request’s method is not a CORS-safelisted method, 4081cb0ef41Sopenharmony_ci // then throw a TypeError. 4091cb0ef41Sopenharmony_ci if (!corsSafeListedMethodsSet.has(request.method)) { 4101cb0ef41Sopenharmony_ci throw new TypeError( 4111cb0ef41Sopenharmony_ci `'${request.method} is unsupported in no-cors mode.` 4121cb0ef41Sopenharmony_ci ) 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ci // 2. Set this’s headers’s guard to "request-no-cors". 4161cb0ef41Sopenharmony_ci this[kHeaders][kGuard] = 'request-no-cors' 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci // 32. If init is not empty, then: 4201cb0ef41Sopenharmony_ci if (initHasKey) { 4211cb0ef41Sopenharmony_ci /** @type {HeadersList} */ 4221cb0ef41Sopenharmony_ci const headersList = this[kHeaders][kHeadersList] 4231cb0ef41Sopenharmony_ci // 1. Let headers be a copy of this’s headers and its associated header 4241cb0ef41Sopenharmony_ci // list. 4251cb0ef41Sopenharmony_ci // 2. If init["headers"] exists, then set headers to init["headers"]. 4261cb0ef41Sopenharmony_ci const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci // 3. Empty this’s headers’s header list. 4291cb0ef41Sopenharmony_ci headersList.clear() 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci // 4. If headers is a Headers object, then for each header in its header 4321cb0ef41Sopenharmony_ci // list, append header’s name/header’s value to this’s headers. 4331cb0ef41Sopenharmony_ci if (headers instanceof HeadersList) { 4341cb0ef41Sopenharmony_ci for (const [key, val] of headers) { 4351cb0ef41Sopenharmony_ci headersList.append(key, val) 4361cb0ef41Sopenharmony_ci } 4371cb0ef41Sopenharmony_ci // Note: Copy the `set-cookie` meta-data. 4381cb0ef41Sopenharmony_ci headersList.cookies = headers.cookies 4391cb0ef41Sopenharmony_ci } else { 4401cb0ef41Sopenharmony_ci // 5. Otherwise, fill this’s headers with headers. 4411cb0ef41Sopenharmony_ci fillHeaders(this[kHeaders], headers) 4421cb0ef41Sopenharmony_ci } 4431cb0ef41Sopenharmony_ci } 4441cb0ef41Sopenharmony_ci 4451cb0ef41Sopenharmony_ci // 33. Let inputBody be input’s request’s body if input is a Request 4461cb0ef41Sopenharmony_ci // object; otherwise null. 4471cb0ef41Sopenharmony_ci const inputBody = input instanceof Request ? input[kState].body : null 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci // 34. If either init["body"] exists and is non-null or inputBody is 4501cb0ef41Sopenharmony_ci // non-null, and request’s method is `GET` or `HEAD`, then throw a 4511cb0ef41Sopenharmony_ci // TypeError. 4521cb0ef41Sopenharmony_ci if ( 4531cb0ef41Sopenharmony_ci (init.body != null || inputBody != null) && 4541cb0ef41Sopenharmony_ci (request.method === 'GET' || request.method === 'HEAD') 4551cb0ef41Sopenharmony_ci ) { 4561cb0ef41Sopenharmony_ci throw new TypeError('Request with GET/HEAD method cannot have body.') 4571cb0ef41Sopenharmony_ci } 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci // 35. Let initBody be null. 4601cb0ef41Sopenharmony_ci let initBody = null 4611cb0ef41Sopenharmony_ci 4621cb0ef41Sopenharmony_ci // 36. If init["body"] exists and is non-null, then: 4631cb0ef41Sopenharmony_ci if (init.body != null) { 4641cb0ef41Sopenharmony_ci // 1. Let Content-Type be null. 4651cb0ef41Sopenharmony_ci // 2. Set initBody and Content-Type to the result of extracting 4661cb0ef41Sopenharmony_ci // init["body"], with keepalive set to request’s keepalive. 4671cb0ef41Sopenharmony_ci const [extractedBody, contentType] = extractBody( 4681cb0ef41Sopenharmony_ci init.body, 4691cb0ef41Sopenharmony_ci request.keepalive 4701cb0ef41Sopenharmony_ci ) 4711cb0ef41Sopenharmony_ci initBody = extractedBody 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_ci // 3, If Content-Type is non-null and this’s headers’s header list does 4741cb0ef41Sopenharmony_ci // not contain `Content-Type`, then append `Content-Type`/Content-Type to 4751cb0ef41Sopenharmony_ci // this’s headers. 4761cb0ef41Sopenharmony_ci if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { 4771cb0ef41Sopenharmony_ci this[kHeaders].append('content-type', contentType) 4781cb0ef41Sopenharmony_ci } 4791cb0ef41Sopenharmony_ci } 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_ci // 37. Let inputOrInitBody be initBody if it is non-null; otherwise 4821cb0ef41Sopenharmony_ci // inputBody. 4831cb0ef41Sopenharmony_ci const inputOrInitBody = initBody ?? inputBody 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_ci // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is 4861cb0ef41Sopenharmony_ci // null, then: 4871cb0ef41Sopenharmony_ci if (inputOrInitBody != null && inputOrInitBody.source == null) { 4881cb0ef41Sopenharmony_ci // 1. If initBody is non-null and init["duplex"] does not exist, 4891cb0ef41Sopenharmony_ci // then throw a TypeError. 4901cb0ef41Sopenharmony_ci if (initBody != null && init.duplex == null) { 4911cb0ef41Sopenharmony_ci throw new TypeError('RequestInit: duplex option is required when sending a body.') 4921cb0ef41Sopenharmony_ci } 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci // 2. If this’s request’s mode is neither "same-origin" nor "cors", 4951cb0ef41Sopenharmony_ci // then throw a TypeError. 4961cb0ef41Sopenharmony_ci if (request.mode !== 'same-origin' && request.mode !== 'cors') { 4971cb0ef41Sopenharmony_ci throw new TypeError( 4981cb0ef41Sopenharmony_ci 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' 4991cb0ef41Sopenharmony_ci ) 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci // 3. Set this’s request’s use-CORS-preflight flag. 5031cb0ef41Sopenharmony_ci request.useCORSPreflightFlag = true 5041cb0ef41Sopenharmony_ci } 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci // 39. Let finalBody be inputOrInitBody. 5071cb0ef41Sopenharmony_ci let finalBody = inputOrInitBody 5081cb0ef41Sopenharmony_ci 5091cb0ef41Sopenharmony_ci // 40. If initBody is null and inputBody is non-null, then: 5101cb0ef41Sopenharmony_ci if (initBody == null && inputBody != null) { 5111cb0ef41Sopenharmony_ci // 1. If input is unusable, then throw a TypeError. 5121cb0ef41Sopenharmony_ci if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { 5131cb0ef41Sopenharmony_ci throw new TypeError( 5141cb0ef41Sopenharmony_ci 'Cannot construct a Request with a Request object that has already been used.' 5151cb0ef41Sopenharmony_ci ) 5161cb0ef41Sopenharmony_ci } 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_ci // 2. Set finalBody to the result of creating a proxy for inputBody. 5191cb0ef41Sopenharmony_ci if (!TransformStream) { 5201cb0ef41Sopenharmony_ci TransformStream = require('stream/web').TransformStream 5211cb0ef41Sopenharmony_ci } 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_ci // https://streams.spec.whatwg.org/#readablestream-create-a-proxy 5241cb0ef41Sopenharmony_ci const identityTransform = new TransformStream() 5251cb0ef41Sopenharmony_ci inputBody.stream.pipeThrough(identityTransform) 5261cb0ef41Sopenharmony_ci finalBody = { 5271cb0ef41Sopenharmony_ci source: inputBody.source, 5281cb0ef41Sopenharmony_ci length: inputBody.length, 5291cb0ef41Sopenharmony_ci stream: identityTransform.readable 5301cb0ef41Sopenharmony_ci } 5311cb0ef41Sopenharmony_ci } 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci // 41. Set this’s request’s body to finalBody. 5341cb0ef41Sopenharmony_ci this[kState].body = finalBody 5351cb0ef41Sopenharmony_ci } 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_ci // Returns request’s HTTP method, which is "GET" by default. 5381cb0ef41Sopenharmony_ci get method () { 5391cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ci // The method getter steps are to return this’s request’s method. 5421cb0ef41Sopenharmony_ci return this[kState].method 5431cb0ef41Sopenharmony_ci } 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci // Returns the URL of request as a string. 5461cb0ef41Sopenharmony_ci get url () { 5471cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci // The url getter steps are to return this’s request’s URL, serialized. 5501cb0ef41Sopenharmony_ci return URLSerializer(this[kState].url) 5511cb0ef41Sopenharmony_ci } 5521cb0ef41Sopenharmony_ci 5531cb0ef41Sopenharmony_ci // Returns a Headers object consisting of the headers associated with request. 5541cb0ef41Sopenharmony_ci // Note that headers added in the network layer by the user agent will not 5551cb0ef41Sopenharmony_ci // be accounted for in this object, e.g., the "Host" header. 5561cb0ef41Sopenharmony_ci get headers () { 5571cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 5581cb0ef41Sopenharmony_ci 5591cb0ef41Sopenharmony_ci // The headers getter steps are to return this’s headers. 5601cb0ef41Sopenharmony_ci return this[kHeaders] 5611cb0ef41Sopenharmony_ci } 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci // Returns the kind of resource requested by request, e.g., "document" 5641cb0ef41Sopenharmony_ci // or "script". 5651cb0ef41Sopenharmony_ci get destination () { 5661cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ci // The destination getter are to return this’s request’s destination. 5691cb0ef41Sopenharmony_ci return this[kState].destination 5701cb0ef41Sopenharmony_ci } 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ci // Returns the referrer of request. Its value can be a same-origin URL if 5731cb0ef41Sopenharmony_ci // explicitly set in init, the empty string to indicate no referrer, and 5741cb0ef41Sopenharmony_ci // "about:client" when defaulting to the global’s default. This is used 5751cb0ef41Sopenharmony_ci // during fetching to determine the value of the `Referer` header of the 5761cb0ef41Sopenharmony_ci // request being made. 5771cb0ef41Sopenharmony_ci get referrer () { 5781cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci // 1. If this’s request’s referrer is "no-referrer", then return the 5811cb0ef41Sopenharmony_ci // empty string. 5821cb0ef41Sopenharmony_ci if (this[kState].referrer === 'no-referrer') { 5831cb0ef41Sopenharmony_ci return '' 5841cb0ef41Sopenharmony_ci } 5851cb0ef41Sopenharmony_ci 5861cb0ef41Sopenharmony_ci // 2. If this’s request’s referrer is "client", then return 5871cb0ef41Sopenharmony_ci // "about:client". 5881cb0ef41Sopenharmony_ci if (this[kState].referrer === 'client') { 5891cb0ef41Sopenharmony_ci return 'about:client' 5901cb0ef41Sopenharmony_ci } 5911cb0ef41Sopenharmony_ci 5921cb0ef41Sopenharmony_ci // Return this’s request’s referrer, serialized. 5931cb0ef41Sopenharmony_ci return this[kState].referrer.toString() 5941cb0ef41Sopenharmony_ci } 5951cb0ef41Sopenharmony_ci 5961cb0ef41Sopenharmony_ci // Returns the referrer policy associated with request. 5971cb0ef41Sopenharmony_ci // This is used during fetching to compute the value of the request’s 5981cb0ef41Sopenharmony_ci // referrer. 5991cb0ef41Sopenharmony_ci get referrerPolicy () { 6001cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_ci // The referrerPolicy getter steps are to return this’s request’s referrer policy. 6031cb0ef41Sopenharmony_ci return this[kState].referrerPolicy 6041cb0ef41Sopenharmony_ci } 6051cb0ef41Sopenharmony_ci 6061cb0ef41Sopenharmony_ci // Returns the mode associated with request, which is a string indicating 6071cb0ef41Sopenharmony_ci // whether the request will use CORS, or will be restricted to same-origin 6081cb0ef41Sopenharmony_ci // URLs. 6091cb0ef41Sopenharmony_ci get mode () { 6101cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6111cb0ef41Sopenharmony_ci 6121cb0ef41Sopenharmony_ci // The mode getter steps are to return this’s request’s mode. 6131cb0ef41Sopenharmony_ci return this[kState].mode 6141cb0ef41Sopenharmony_ci } 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci // Returns the credentials mode associated with request, 6171cb0ef41Sopenharmony_ci // which is a string indicating whether credentials will be sent with the 6181cb0ef41Sopenharmony_ci // request always, never, or only when sent to a same-origin URL. 6191cb0ef41Sopenharmony_ci get credentials () { 6201cb0ef41Sopenharmony_ci // The credentials getter steps are to return this’s request’s credentials mode. 6211cb0ef41Sopenharmony_ci return this[kState].credentials 6221cb0ef41Sopenharmony_ci } 6231cb0ef41Sopenharmony_ci 6241cb0ef41Sopenharmony_ci // Returns the cache mode associated with request, 6251cb0ef41Sopenharmony_ci // which is a string indicating how the request will 6261cb0ef41Sopenharmony_ci // interact with the browser’s cache when fetching. 6271cb0ef41Sopenharmony_ci get cache () { 6281cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6291cb0ef41Sopenharmony_ci 6301cb0ef41Sopenharmony_ci // The cache getter steps are to return this’s request’s cache mode. 6311cb0ef41Sopenharmony_ci return this[kState].cache 6321cb0ef41Sopenharmony_ci } 6331cb0ef41Sopenharmony_ci 6341cb0ef41Sopenharmony_ci // Returns the redirect mode associated with request, 6351cb0ef41Sopenharmony_ci // which is a string indicating how redirects for the 6361cb0ef41Sopenharmony_ci // request will be handled during fetching. A request 6371cb0ef41Sopenharmony_ci // will follow redirects by default. 6381cb0ef41Sopenharmony_ci get redirect () { 6391cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6401cb0ef41Sopenharmony_ci 6411cb0ef41Sopenharmony_ci // The redirect getter steps are to return this’s request’s redirect mode. 6421cb0ef41Sopenharmony_ci return this[kState].redirect 6431cb0ef41Sopenharmony_ci } 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci // Returns request’s subresource integrity metadata, which is a 6461cb0ef41Sopenharmony_ci // cryptographic hash of the resource being fetched. Its value 6471cb0ef41Sopenharmony_ci // consists of multiple hashes separated by whitespace. [SRI] 6481cb0ef41Sopenharmony_ci get integrity () { 6491cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci // The integrity getter steps are to return this’s request’s integrity 6521cb0ef41Sopenharmony_ci // metadata. 6531cb0ef41Sopenharmony_ci return this[kState].integrity 6541cb0ef41Sopenharmony_ci } 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci // Returns a boolean indicating whether or not request can outlive the 6571cb0ef41Sopenharmony_ci // global in which it was created. 6581cb0ef41Sopenharmony_ci get keepalive () { 6591cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci // The keepalive getter steps are to return this’s request’s keepalive. 6621cb0ef41Sopenharmony_ci return this[kState].keepalive 6631cb0ef41Sopenharmony_ci } 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci // Returns a boolean indicating whether or not request is for a reload 6661cb0ef41Sopenharmony_ci // navigation. 6671cb0ef41Sopenharmony_ci get isReloadNavigation () { 6681cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6691cb0ef41Sopenharmony_ci 6701cb0ef41Sopenharmony_ci // The isReloadNavigation getter steps are to return true if this’s 6711cb0ef41Sopenharmony_ci // request’s reload-navigation flag is set; otherwise false. 6721cb0ef41Sopenharmony_ci return this[kState].reloadNavigation 6731cb0ef41Sopenharmony_ci } 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci // Returns a boolean indicating whether or not request is for a history 6761cb0ef41Sopenharmony_ci // navigation (a.k.a. back-foward navigation). 6771cb0ef41Sopenharmony_ci get isHistoryNavigation () { 6781cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6791cb0ef41Sopenharmony_ci 6801cb0ef41Sopenharmony_ci // The isHistoryNavigation getter steps are to return true if this’s request’s 6811cb0ef41Sopenharmony_ci // history-navigation flag is set; otherwise false. 6821cb0ef41Sopenharmony_ci return this[kState].historyNavigation 6831cb0ef41Sopenharmony_ci } 6841cb0ef41Sopenharmony_ci 6851cb0ef41Sopenharmony_ci // Returns the signal associated with request, which is an AbortSignal 6861cb0ef41Sopenharmony_ci // object indicating whether or not request has been aborted, and its 6871cb0ef41Sopenharmony_ci // abort event handler. 6881cb0ef41Sopenharmony_ci get signal () { 6891cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6901cb0ef41Sopenharmony_ci 6911cb0ef41Sopenharmony_ci // The signal getter steps are to return this’s signal. 6921cb0ef41Sopenharmony_ci return this[kSignal] 6931cb0ef41Sopenharmony_ci } 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci get body () { 6961cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 6971cb0ef41Sopenharmony_ci 6981cb0ef41Sopenharmony_ci return this[kState].body ? this[kState].body.stream : null 6991cb0ef41Sopenharmony_ci } 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_ci get bodyUsed () { 7021cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 7031cb0ef41Sopenharmony_ci 7041cb0ef41Sopenharmony_ci return !!this[kState].body && util.isDisturbed(this[kState].body.stream) 7051cb0ef41Sopenharmony_ci } 7061cb0ef41Sopenharmony_ci 7071cb0ef41Sopenharmony_ci get duplex () { 7081cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 7091cb0ef41Sopenharmony_ci 7101cb0ef41Sopenharmony_ci return 'half' 7111cb0ef41Sopenharmony_ci } 7121cb0ef41Sopenharmony_ci 7131cb0ef41Sopenharmony_ci // Returns a clone of request. 7141cb0ef41Sopenharmony_ci clone () { 7151cb0ef41Sopenharmony_ci webidl.brandCheck(this, Request) 7161cb0ef41Sopenharmony_ci 7171cb0ef41Sopenharmony_ci // 1. If this is unusable, then throw a TypeError. 7181cb0ef41Sopenharmony_ci if (this.bodyUsed || this.body?.locked) { 7191cb0ef41Sopenharmony_ci throw new TypeError('unusable') 7201cb0ef41Sopenharmony_ci } 7211cb0ef41Sopenharmony_ci 7221cb0ef41Sopenharmony_ci // 2. Let clonedRequest be the result of cloning this’s request. 7231cb0ef41Sopenharmony_ci const clonedRequest = cloneRequest(this[kState]) 7241cb0ef41Sopenharmony_ci 7251cb0ef41Sopenharmony_ci // 3. Let clonedRequestObject be the result of creating a Request object, 7261cb0ef41Sopenharmony_ci // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. 7271cb0ef41Sopenharmony_ci const clonedRequestObject = new Request(kConstruct) 7281cb0ef41Sopenharmony_ci clonedRequestObject[kState] = clonedRequest 7291cb0ef41Sopenharmony_ci clonedRequestObject[kRealm] = this[kRealm] 7301cb0ef41Sopenharmony_ci clonedRequestObject[kHeaders] = new Headers(kConstruct) 7311cb0ef41Sopenharmony_ci clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList 7321cb0ef41Sopenharmony_ci clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] 7331cb0ef41Sopenharmony_ci clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci // 4. Make clonedRequestObject’s signal follow this’s signal. 7361cb0ef41Sopenharmony_ci const ac = new AbortController() 7371cb0ef41Sopenharmony_ci if (this.signal.aborted) { 7381cb0ef41Sopenharmony_ci ac.abort(this.signal.reason) 7391cb0ef41Sopenharmony_ci } else { 7401cb0ef41Sopenharmony_ci util.addAbortListener( 7411cb0ef41Sopenharmony_ci this.signal, 7421cb0ef41Sopenharmony_ci () => { 7431cb0ef41Sopenharmony_ci ac.abort(this.signal.reason) 7441cb0ef41Sopenharmony_ci } 7451cb0ef41Sopenharmony_ci ) 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci clonedRequestObject[kSignal] = ac.signal 7481cb0ef41Sopenharmony_ci 7491cb0ef41Sopenharmony_ci // 4. Return clonedRequestObject. 7501cb0ef41Sopenharmony_ci return clonedRequestObject 7511cb0ef41Sopenharmony_ci } 7521cb0ef41Sopenharmony_ci} 7531cb0ef41Sopenharmony_ci 7541cb0ef41Sopenharmony_cimixinBody(Request) 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_cifunction makeRequest (init) { 7571cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#requests 7581cb0ef41Sopenharmony_ci const request = { 7591cb0ef41Sopenharmony_ci method: 'GET', 7601cb0ef41Sopenharmony_ci localURLsOnly: false, 7611cb0ef41Sopenharmony_ci unsafeRequest: false, 7621cb0ef41Sopenharmony_ci body: null, 7631cb0ef41Sopenharmony_ci client: null, 7641cb0ef41Sopenharmony_ci reservedClient: null, 7651cb0ef41Sopenharmony_ci replacesClientId: '', 7661cb0ef41Sopenharmony_ci window: 'client', 7671cb0ef41Sopenharmony_ci keepalive: false, 7681cb0ef41Sopenharmony_ci serviceWorkers: 'all', 7691cb0ef41Sopenharmony_ci initiator: '', 7701cb0ef41Sopenharmony_ci destination: '', 7711cb0ef41Sopenharmony_ci priority: null, 7721cb0ef41Sopenharmony_ci origin: 'client', 7731cb0ef41Sopenharmony_ci policyContainer: 'client', 7741cb0ef41Sopenharmony_ci referrer: 'client', 7751cb0ef41Sopenharmony_ci referrerPolicy: '', 7761cb0ef41Sopenharmony_ci mode: 'no-cors', 7771cb0ef41Sopenharmony_ci useCORSPreflightFlag: false, 7781cb0ef41Sopenharmony_ci credentials: 'same-origin', 7791cb0ef41Sopenharmony_ci useCredentials: false, 7801cb0ef41Sopenharmony_ci cache: 'default', 7811cb0ef41Sopenharmony_ci redirect: 'follow', 7821cb0ef41Sopenharmony_ci integrity: '', 7831cb0ef41Sopenharmony_ci cryptoGraphicsNonceMetadata: '', 7841cb0ef41Sopenharmony_ci parserMetadata: '', 7851cb0ef41Sopenharmony_ci reloadNavigation: false, 7861cb0ef41Sopenharmony_ci historyNavigation: false, 7871cb0ef41Sopenharmony_ci userActivation: false, 7881cb0ef41Sopenharmony_ci taintedOrigin: false, 7891cb0ef41Sopenharmony_ci redirectCount: 0, 7901cb0ef41Sopenharmony_ci responseTainting: 'basic', 7911cb0ef41Sopenharmony_ci preventNoCacheCacheControlHeaderModification: false, 7921cb0ef41Sopenharmony_ci done: false, 7931cb0ef41Sopenharmony_ci timingAllowFailed: false, 7941cb0ef41Sopenharmony_ci ...init, 7951cb0ef41Sopenharmony_ci headersList: init.headersList 7961cb0ef41Sopenharmony_ci ? new HeadersList(init.headersList) 7971cb0ef41Sopenharmony_ci : new HeadersList() 7981cb0ef41Sopenharmony_ci } 7991cb0ef41Sopenharmony_ci request.url = request.urlList[0] 8001cb0ef41Sopenharmony_ci return request 8011cb0ef41Sopenharmony_ci} 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_ci// https://fetch.spec.whatwg.org/#concept-request-clone 8041cb0ef41Sopenharmony_cifunction cloneRequest (request) { 8051cb0ef41Sopenharmony_ci // To clone a request request, run these steps: 8061cb0ef41Sopenharmony_ci 8071cb0ef41Sopenharmony_ci // 1. Let newRequest be a copy of request, except for its body. 8081cb0ef41Sopenharmony_ci const newRequest = makeRequest({ ...request, body: null }) 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_ci // 2. If request’s body is non-null, set newRequest’s body to the 8111cb0ef41Sopenharmony_ci // result of cloning request’s body. 8121cb0ef41Sopenharmony_ci if (request.body != null) { 8131cb0ef41Sopenharmony_ci newRequest.body = cloneBody(request.body) 8141cb0ef41Sopenharmony_ci } 8151cb0ef41Sopenharmony_ci 8161cb0ef41Sopenharmony_ci // 3. Return newRequest. 8171cb0ef41Sopenharmony_ci return newRequest 8181cb0ef41Sopenharmony_ci} 8191cb0ef41Sopenharmony_ci 8201cb0ef41Sopenharmony_ciObject.defineProperties(Request.prototype, { 8211cb0ef41Sopenharmony_ci method: kEnumerableProperty, 8221cb0ef41Sopenharmony_ci url: kEnumerableProperty, 8231cb0ef41Sopenharmony_ci headers: kEnumerableProperty, 8241cb0ef41Sopenharmony_ci redirect: kEnumerableProperty, 8251cb0ef41Sopenharmony_ci clone: kEnumerableProperty, 8261cb0ef41Sopenharmony_ci signal: kEnumerableProperty, 8271cb0ef41Sopenharmony_ci duplex: kEnumerableProperty, 8281cb0ef41Sopenharmony_ci destination: kEnumerableProperty, 8291cb0ef41Sopenharmony_ci body: kEnumerableProperty, 8301cb0ef41Sopenharmony_ci bodyUsed: kEnumerableProperty, 8311cb0ef41Sopenharmony_ci isHistoryNavigation: kEnumerableProperty, 8321cb0ef41Sopenharmony_ci isReloadNavigation: kEnumerableProperty, 8331cb0ef41Sopenharmony_ci keepalive: kEnumerableProperty, 8341cb0ef41Sopenharmony_ci integrity: kEnumerableProperty, 8351cb0ef41Sopenharmony_ci cache: kEnumerableProperty, 8361cb0ef41Sopenharmony_ci credentials: kEnumerableProperty, 8371cb0ef41Sopenharmony_ci attribute: kEnumerableProperty, 8381cb0ef41Sopenharmony_ci referrerPolicy: kEnumerableProperty, 8391cb0ef41Sopenharmony_ci referrer: kEnumerableProperty, 8401cb0ef41Sopenharmony_ci mode: kEnumerableProperty, 8411cb0ef41Sopenharmony_ci [Symbol.toStringTag]: { 8421cb0ef41Sopenharmony_ci value: 'Request', 8431cb0ef41Sopenharmony_ci configurable: true 8441cb0ef41Sopenharmony_ci } 8451cb0ef41Sopenharmony_ci}) 8461cb0ef41Sopenharmony_ci 8471cb0ef41Sopenharmony_ciwebidl.converters.Request = webidl.interfaceConverter( 8481cb0ef41Sopenharmony_ci Request 8491cb0ef41Sopenharmony_ci) 8501cb0ef41Sopenharmony_ci 8511cb0ef41Sopenharmony_ci// https://fetch.spec.whatwg.org/#requestinfo 8521cb0ef41Sopenharmony_ciwebidl.converters.RequestInfo = function (V) { 8531cb0ef41Sopenharmony_ci if (typeof V === 'string') { 8541cb0ef41Sopenharmony_ci return webidl.converters.USVString(V) 8551cb0ef41Sopenharmony_ci } 8561cb0ef41Sopenharmony_ci 8571cb0ef41Sopenharmony_ci if (V instanceof Request) { 8581cb0ef41Sopenharmony_ci return webidl.converters.Request(V) 8591cb0ef41Sopenharmony_ci } 8601cb0ef41Sopenharmony_ci 8611cb0ef41Sopenharmony_ci return webidl.converters.USVString(V) 8621cb0ef41Sopenharmony_ci} 8631cb0ef41Sopenharmony_ci 8641cb0ef41Sopenharmony_ciwebidl.converters.AbortSignal = webidl.interfaceConverter( 8651cb0ef41Sopenharmony_ci AbortSignal 8661cb0ef41Sopenharmony_ci) 8671cb0ef41Sopenharmony_ci 8681cb0ef41Sopenharmony_ci// https://fetch.spec.whatwg.org/#requestinit 8691cb0ef41Sopenharmony_ciwebidl.converters.RequestInit = webidl.dictionaryConverter([ 8701cb0ef41Sopenharmony_ci { 8711cb0ef41Sopenharmony_ci key: 'method', 8721cb0ef41Sopenharmony_ci converter: webidl.converters.ByteString 8731cb0ef41Sopenharmony_ci }, 8741cb0ef41Sopenharmony_ci { 8751cb0ef41Sopenharmony_ci key: 'headers', 8761cb0ef41Sopenharmony_ci converter: webidl.converters.HeadersInit 8771cb0ef41Sopenharmony_ci }, 8781cb0ef41Sopenharmony_ci { 8791cb0ef41Sopenharmony_ci key: 'body', 8801cb0ef41Sopenharmony_ci converter: webidl.nullableConverter( 8811cb0ef41Sopenharmony_ci webidl.converters.BodyInit 8821cb0ef41Sopenharmony_ci ) 8831cb0ef41Sopenharmony_ci }, 8841cb0ef41Sopenharmony_ci { 8851cb0ef41Sopenharmony_ci key: 'referrer', 8861cb0ef41Sopenharmony_ci converter: webidl.converters.USVString 8871cb0ef41Sopenharmony_ci }, 8881cb0ef41Sopenharmony_ci { 8891cb0ef41Sopenharmony_ci key: 'referrerPolicy', 8901cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 8911cb0ef41Sopenharmony_ci // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy 8921cb0ef41Sopenharmony_ci allowedValues: referrerPolicy 8931cb0ef41Sopenharmony_ci }, 8941cb0ef41Sopenharmony_ci { 8951cb0ef41Sopenharmony_ci key: 'mode', 8961cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 8971cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#concept-request-mode 8981cb0ef41Sopenharmony_ci allowedValues: requestMode 8991cb0ef41Sopenharmony_ci }, 9001cb0ef41Sopenharmony_ci { 9011cb0ef41Sopenharmony_ci key: 'credentials', 9021cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 9031cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#requestcredentials 9041cb0ef41Sopenharmony_ci allowedValues: requestCredentials 9051cb0ef41Sopenharmony_ci }, 9061cb0ef41Sopenharmony_ci { 9071cb0ef41Sopenharmony_ci key: 'cache', 9081cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 9091cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#requestcache 9101cb0ef41Sopenharmony_ci allowedValues: requestCache 9111cb0ef41Sopenharmony_ci }, 9121cb0ef41Sopenharmony_ci { 9131cb0ef41Sopenharmony_ci key: 'redirect', 9141cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 9151cb0ef41Sopenharmony_ci // https://fetch.spec.whatwg.org/#requestredirect 9161cb0ef41Sopenharmony_ci allowedValues: requestRedirect 9171cb0ef41Sopenharmony_ci }, 9181cb0ef41Sopenharmony_ci { 9191cb0ef41Sopenharmony_ci key: 'integrity', 9201cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString 9211cb0ef41Sopenharmony_ci }, 9221cb0ef41Sopenharmony_ci { 9231cb0ef41Sopenharmony_ci key: 'keepalive', 9241cb0ef41Sopenharmony_ci converter: webidl.converters.boolean 9251cb0ef41Sopenharmony_ci }, 9261cb0ef41Sopenharmony_ci { 9271cb0ef41Sopenharmony_ci key: 'signal', 9281cb0ef41Sopenharmony_ci converter: webidl.nullableConverter( 9291cb0ef41Sopenharmony_ci (signal) => webidl.converters.AbortSignal( 9301cb0ef41Sopenharmony_ci signal, 9311cb0ef41Sopenharmony_ci { strict: false } 9321cb0ef41Sopenharmony_ci ) 9331cb0ef41Sopenharmony_ci ) 9341cb0ef41Sopenharmony_ci }, 9351cb0ef41Sopenharmony_ci { 9361cb0ef41Sopenharmony_ci key: 'window', 9371cb0ef41Sopenharmony_ci converter: webidl.converters.any 9381cb0ef41Sopenharmony_ci }, 9391cb0ef41Sopenharmony_ci { 9401cb0ef41Sopenharmony_ci key: 'duplex', 9411cb0ef41Sopenharmony_ci converter: webidl.converters.DOMString, 9421cb0ef41Sopenharmony_ci allowedValues: requestDuplex 9431cb0ef41Sopenharmony_ci } 9441cb0ef41Sopenharmony_ci]) 9451cb0ef41Sopenharmony_ci 9461cb0ef41Sopenharmony_cimodule.exports = { Request, makeRequest } 947