1'use strict' 2 3const { MessageChannel, receiveMessageOnPort } = require('worker_threads') 4 5const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] 6 7const nullBodyStatus = [101, 204, 205, 304] 8 9const redirectStatus = [301, 302, 303, 307, 308] 10 11// https://fetch.spec.whatwg.org/#block-bad-port 12const badPorts = [ 13 '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', 14 '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', 15 '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', 16 '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', 17 '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', 18 '10080' 19] 20 21// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies 22const referrerPolicy = [ 23 '', 24 'no-referrer', 25 'no-referrer-when-downgrade', 26 'same-origin', 27 'origin', 28 'strict-origin', 29 'origin-when-cross-origin', 30 'strict-origin-when-cross-origin', 31 'unsafe-url' 32] 33 34const requestRedirect = ['follow', 'manual', 'error'] 35 36const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] 37 38const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] 39 40const requestCredentials = ['omit', 'same-origin', 'include'] 41 42const requestCache = [ 43 'default', 44 'no-store', 45 'reload', 46 'no-cache', 47 'force-cache', 48 'only-if-cached' 49] 50 51// https://fetch.spec.whatwg.org/#request-body-header-name 52const requestBodyHeader = [ 53 'content-encoding', 54 'content-language', 55 'content-location', 56 'content-type', 57 // See https://github.com/nodejs/undici/issues/2021 58 // 'Content-Length' is a forbidden header name, which is typically 59 // removed in the Headers implementation. However, undici doesn't 60 // filter out headers, so we add it here. 61 'content-length' 62] 63 64// https://fetch.spec.whatwg.org/#enumdef-requestduplex 65const requestDuplex = [ 66 'half' 67] 68 69// http://fetch.spec.whatwg.org/#forbidden-method 70const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] 71 72const subresource = [ 73 'audio', 74 'audioworklet', 75 'font', 76 'image', 77 'manifest', 78 'paintworklet', 79 'script', 80 'style', 81 'track', 82 'video', 83 'xslt', 84 '' 85] 86 87/** @type {globalThis['DOMException']} */ 88const DOMException = globalThis.DOMException ?? (() => { 89 // DOMException was only made a global in Node v17.0.0, 90 // but fetch supports >= v16.8. 91 try { 92 atob('~') 93 } catch (err) { 94 return Object.getPrototypeOf(err).constructor 95 } 96})() 97 98let channel 99 100/** @type {globalThis['structuredClone']} */ 101const structuredClone = 102 globalThis.structuredClone ?? 103 // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js 104 // structuredClone was added in v17.0.0, but fetch supports v16.8 105 function structuredClone (value, options = undefined) { 106 if (arguments.length === 0) { 107 throw new TypeError('missing argument') 108 } 109 110 if (!channel) { 111 channel = new MessageChannel() 112 } 113 channel.port1.unref() 114 channel.port2.unref() 115 channel.port1.postMessage(value, options?.transfer) 116 return receiveMessageOnPort(channel.port2).message 117 } 118 119module.exports = { 120 DOMException, 121 structuredClone, 122 subresource, 123 forbiddenMethods, 124 requestBodyHeader, 125 referrerPolicy, 126 requestRedirect, 127 requestMode, 128 requestCredentials, 129 requestCache, 130 redirectStatus, 131 corsSafeListedMethods, 132 nullBodyStatus, 133 safeMethods, 134 badPorts, 135 requestDuplex 136} 137