• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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