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