@nocobase/plugin-idp-oauth 2.1.0-alpha.17 → 2.1.0-alpha.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/build.config.ts +1 -1
  2. package/dist/externalVersion.js +6 -4
  3. package/dist/node_modules/light-my-request/package.json +1 -1
  4. package/dist/node_modules/undici/LICENSE +21 -0
  5. package/dist/node_modules/undici/README.md +741 -0
  6. package/dist/node_modules/undici/docs/docs/api/Agent.md +84 -0
  7. package/dist/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  8. package/dist/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  9. package/dist/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
  10. package/dist/node_modules/undici/docs/docs/api/Client.md +285 -0
  11. package/dist/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  12. package/dist/node_modules/undici/docs/docs/api/Connector.md +115 -0
  13. package/dist/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  14. package/dist/node_modules/undici/docs/docs/api/Cookies.md +101 -0
  15. package/dist/node_modules/undici/docs/docs/api/Debug.md +62 -0
  16. package/dist/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
  17. package/dist/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
  18. package/dist/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  19. package/dist/node_modules/undici/docs/docs/api/Errors.md +49 -0
  20. package/dist/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  21. package/dist/node_modules/undici/docs/docs/api/Fetch.md +60 -0
  22. package/dist/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
  23. package/dist/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
  24. package/dist/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  25. package/dist/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  26. package/dist/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  27. package/dist/node_modules/undici/docs/docs/api/MockClient.md +81 -0
  28. package/dist/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  29. package/dist/node_modules/undici/docs/docs/api/MockPool.md +555 -0
  30. package/dist/node_modules/undici/docs/docs/api/Pool.md +84 -0
  31. package/dist/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  32. package/dist/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
  33. package/dist/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
  34. package/dist/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
  35. package/dist/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
  36. package/dist/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
  37. package/dist/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
  38. package/dist/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +274 -0
  39. package/dist/node_modules/undici/docs/docs/api/Util.md +25 -0
  40. package/dist/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
  41. package/dist/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  42. package/dist/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  43. package/dist/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
  44. package/dist/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  45. package/dist/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  46. package/dist/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
  47. package/dist/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
  48. package/dist/node_modules/undici/index-fetch.js +65 -0
  49. package/dist/node_modules/undici/index.d.ts +3 -0
  50. package/dist/node_modules/undici/index.js +234 -0
  51. package/dist/node_modules/undici/lib/api/abort-signal.js +59 -0
  52. package/dist/node_modules/undici/lib/api/api-connect.js +110 -0
  53. package/dist/node_modules/undici/lib/api/api-pipeline.js +252 -0
  54. package/dist/node_modules/undici/lib/api/api-request.js +214 -0
  55. package/dist/node_modules/undici/lib/api/api-stream.js +209 -0
  56. package/dist/node_modules/undici/lib/api/api-upgrade.js +111 -0
  57. package/dist/node_modules/undici/lib/api/index.js +7 -0
  58. package/dist/node_modules/undici/lib/api/readable.js +580 -0
  59. package/dist/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
  60. package/dist/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
  61. package/dist/node_modules/undici/lib/core/connect.js +137 -0
  62. package/dist/node_modules/undici/lib/core/constants.js +143 -0
  63. package/dist/node_modules/undici/lib/core/diagnostics.js +227 -0
  64. package/dist/node_modules/undici/lib/core/errors.js +477 -0
  65. package/dist/node_modules/undici/lib/core/request.js +438 -0
  66. package/dist/node_modules/undici/lib/core/socks5-client.js +407 -0
  67. package/dist/node_modules/undici/lib/core/socks5-utils.js +203 -0
  68. package/dist/node_modules/undici/lib/core/symbols.js +75 -0
  69. package/dist/node_modules/undici/lib/core/tree.js +160 -0
  70. package/dist/node_modules/undici/lib/core/util.js +992 -0
  71. package/dist/node_modules/undici/lib/dispatcher/agent.js +158 -0
  72. package/dist/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
  73. package/dist/node_modules/undici/lib/dispatcher/client-h1.js +1610 -0
  74. package/dist/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
  75. package/dist/node_modules/undici/lib/dispatcher/client.js +659 -0
  76. package/dist/node_modules/undici/lib/dispatcher/dispatcher-base.js +165 -0
  77. package/dist/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  78. package/dist/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  79. package/dist/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  80. package/dist/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  81. package/dist/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  82. package/dist/node_modules/undici/lib/dispatcher/pool.js +118 -0
  83. package/dist/node_modules/undici/lib/dispatcher/proxy-agent.js +318 -0
  84. package/dist/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  85. package/dist/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  86. package/dist/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +249 -0
  87. package/dist/node_modules/undici/lib/encoding/index.js +33 -0
  88. package/dist/node_modules/undici/lib/global.js +50 -0
  89. package/dist/node_modules/undici/lib/handler/cache-handler.js +578 -0
  90. package/dist/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  91. package/dist/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  92. package/dist/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
  93. package/dist/node_modules/undici/lib/handler/redirect-handler.js +238 -0
  94. package/dist/node_modules/undici/lib/handler/retry-handler.js +394 -0
  95. package/dist/node_modules/undici/lib/handler/unwrap-handler.js +100 -0
  96. package/dist/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  97. package/dist/node_modules/undici/lib/interceptor/cache.js +495 -0
  98. package/dist/node_modules/undici/lib/interceptor/decompress.js +259 -0
  99. package/dist/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  100. package/dist/node_modules/undici/lib/interceptor/dns.js +571 -0
  101. package/dist/node_modules/undici/lib/interceptor/dump.js +112 -0
  102. package/dist/node_modules/undici/lib/interceptor/redirect.js +21 -0
  103. package/dist/node_modules/undici/lib/interceptor/response-error.js +95 -0
  104. package/dist/node_modules/undici/lib/interceptor/retry.js +19 -0
  105. package/dist/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  106. package/dist/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  107. package/dist/node_modules/undici/lib/llhttp/constants.js +531 -0
  108. package/dist/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  109. package/dist/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  110. package/dist/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  111. package/dist/node_modules/undici/lib/llhttp/utils.js +12 -0
  112. package/dist/node_modules/undici/lib/mock/mock-agent.js +232 -0
  113. package/dist/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  114. package/dist/node_modules/undici/lib/mock/mock-client.js +68 -0
  115. package/dist/node_modules/undici/lib/mock/mock-errors.js +29 -0
  116. package/dist/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  117. package/dist/node_modules/undici/lib/mock/mock-pool.js +68 -0
  118. package/dist/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  119. package/dist/node_modules/undici/lib/mock/mock-utils.js +486 -0
  120. package/dist/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  121. package/dist/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  122. package/dist/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  123. package/dist/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  124. package/dist/node_modules/undici/lib/util/cache.js +407 -0
  125. package/dist/node_modules/undici/lib/util/date.js +653 -0
  126. package/dist/node_modules/undici/lib/util/promise.js +28 -0
  127. package/dist/node_modules/undici/lib/util/runtime-features.js +124 -0
  128. package/dist/node_modules/undici/lib/util/stats.js +32 -0
  129. package/dist/node_modules/undici/lib/util/timers.js +425 -0
  130. package/dist/node_modules/undici/lib/web/cache/cache.js +864 -0
  131. package/dist/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  132. package/dist/node_modules/undici/lib/web/cache/util.js +45 -0
  133. package/dist/node_modules/undici/lib/web/cookies/constants.js +12 -0
  134. package/dist/node_modules/undici/lib/web/cookies/index.js +199 -0
  135. package/dist/node_modules/undici/lib/web/cookies/parse.js +322 -0
  136. package/dist/node_modules/undici/lib/web/cookies/util.js +282 -0
  137. package/dist/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
  138. package/dist/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
  139. package/dist/node_modules/undici/lib/web/eventsource/util.js +29 -0
  140. package/dist/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  141. package/dist/node_modules/undici/lib/web/fetch/body.js +509 -0
  142. package/dist/node_modules/undici/lib/web/fetch/constants.js +131 -0
  143. package/dist/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  144. package/dist/node_modules/undici/lib/web/fetch/formdata-parser.js +575 -0
  145. package/dist/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  146. package/dist/node_modules/undici/lib/web/fetch/global.js +40 -0
  147. package/dist/node_modules/undici/lib/web/fetch/headers.js +719 -0
  148. package/dist/node_modules/undici/lib/web/fetch/index.js +2397 -0
  149. package/dist/node_modules/undici/lib/web/fetch/request.js +1115 -0
  150. package/dist/node_modules/undici/lib/web/fetch/response.js +641 -0
  151. package/dist/node_modules/undici/lib/web/fetch/util.js +1520 -0
  152. package/dist/node_modules/undici/lib/web/infra/index.js +229 -0
  153. package/dist/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  154. package/dist/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  155. package/dist/node_modules/undici/lib/web/webidl/index.js +1006 -0
  156. package/dist/node_modules/undici/lib/web/websocket/connection.js +329 -0
  157. package/dist/node_modules/undici/lib/web/websocket/constants.js +126 -0
  158. package/dist/node_modules/undici/lib/web/websocket/events.js +331 -0
  159. package/dist/node_modules/undici/lib/web/websocket/frame.js +133 -0
  160. package/dist/node_modules/undici/lib/web/websocket/permessage-deflate.js +118 -0
  161. package/dist/node_modules/undici/lib/web/websocket/receiver.js +450 -0
  162. package/dist/node_modules/undici/lib/web/websocket/sender.js +109 -0
  163. package/dist/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  164. package/dist/node_modules/undici/lib/web/websocket/stream/websocketstream.js +497 -0
  165. package/dist/node_modules/undici/lib/web/websocket/util.js +347 -0
  166. package/dist/node_modules/undici/lib/web/websocket/websocket.js +751 -0
  167. package/dist/node_modules/undici/package.json +152 -0
  168. package/dist/node_modules/undici/scripts/strip-comments.js +10 -0
  169. package/dist/node_modules/undici/types/README.md +6 -0
  170. package/dist/node_modules/undici/types/agent.d.ts +32 -0
  171. package/dist/node_modules/undici/types/api.d.ts +43 -0
  172. package/dist/node_modules/undici/types/balanced-pool.d.ts +30 -0
  173. package/dist/node_modules/undici/types/cache-interceptor.d.ts +179 -0
  174. package/dist/node_modules/undici/types/cache.d.ts +36 -0
  175. package/dist/node_modules/undici/types/client-stats.d.ts +15 -0
  176. package/dist/node_modules/undici/types/client.d.ts +123 -0
  177. package/dist/node_modules/undici/types/connector.d.ts +36 -0
  178. package/dist/node_modules/undici/types/content-type.d.ts +21 -0
  179. package/dist/node_modules/undici/types/cookies.d.ts +30 -0
  180. package/dist/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
  181. package/dist/node_modules/undici/types/dispatcher.d.ts +273 -0
  182. package/dist/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  183. package/dist/node_modules/undici/types/errors.d.ts +177 -0
  184. package/dist/node_modules/undici/types/eventsource.d.ts +66 -0
  185. package/dist/node_modules/undici/types/fetch.d.ts +231 -0
  186. package/dist/node_modules/undici/types/formdata.d.ts +114 -0
  187. package/dist/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  188. package/dist/node_modules/undici/types/global-origin.d.ts +7 -0
  189. package/dist/node_modules/undici/types/h2c-client.d.ts +73 -0
  190. package/dist/node_modules/undici/types/handlers.d.ts +14 -0
  191. package/dist/node_modules/undici/types/header.d.ts +160 -0
  192. package/dist/node_modules/undici/types/index.d.ts +91 -0
  193. package/dist/node_modules/undici/types/interceptors.d.ts +80 -0
  194. package/dist/node_modules/undici/types/mock-agent.d.ts +68 -0
  195. package/dist/node_modules/undici/types/mock-call-history.d.ts +111 -0
  196. package/dist/node_modules/undici/types/mock-client.d.ts +27 -0
  197. package/dist/node_modules/undici/types/mock-errors.d.ts +12 -0
  198. package/dist/node_modules/undici/types/mock-interceptor.d.ts +94 -0
  199. package/dist/node_modules/undici/types/mock-pool.d.ts +27 -0
  200. package/dist/node_modules/undici/types/patch.d.ts +29 -0
  201. package/dist/node_modules/undici/types/pool-stats.d.ts +19 -0
  202. package/dist/node_modules/undici/types/pool.d.ts +41 -0
  203. package/dist/node_modules/undici/types/proxy-agent.d.ts +29 -0
  204. package/dist/node_modules/undici/types/readable.d.ts +68 -0
  205. package/dist/node_modules/undici/types/retry-agent.d.ts +8 -0
  206. package/dist/node_modules/undici/types/retry-handler.d.ts +125 -0
  207. package/dist/node_modules/undici/types/round-robin-pool.d.ts +41 -0
  208. package/dist/node_modules/undici/types/snapshot-agent.d.ts +109 -0
  209. package/dist/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
  210. package/dist/node_modules/undici/types/util.d.ts +18 -0
  211. package/dist/node_modules/undici/types/utility.d.ts +7 -0
  212. package/dist/node_modules/undici/types/webidl.d.ts +347 -0
  213. package/dist/node_modules/undici/types/websocket.d.ts +188 -0
  214. package/dist/server/collections/oidcStates.d.ts +10 -0
  215. package/dist/server/collections/oidcStates.js +96 -0
  216. package/dist/server/db-adapter.d.ts +25 -0
  217. package/dist/server/db-adapter.js +156 -0
  218. package/dist/server/service.js +11 -10
  219. package/package.json +2 -2
  220. package/dist/server/cache-adapter.d.ts +0 -33
  221. package/dist/server/cache-adapter.js +0 -159
@@ -0,0 +1,992 @@
1
+ 'use strict'
2
+
3
+ const assert = require('node:assert')
4
+ const { kDestroyed, kBodyUsed, kListeners, kBody } = require('./symbols')
5
+ const { IncomingMessage } = require('node:http')
6
+ const stream = require('node:stream')
7
+ const net = require('node:net')
8
+ const { stringify } = require('node:querystring')
9
+ const { EventEmitter: EE } = require('node:events')
10
+ const timers = require('../util/timers')
11
+ const { InvalidArgumentError, ConnectTimeoutError } = require('./errors')
12
+ const { headerNameLowerCasedRecord } = require('./constants')
13
+ const { tree } = require('./tree')
14
+
15
+ const [nodeMajor, nodeMinor] = process.versions.node.split('.', 2).map(v => Number(v))
16
+
17
+ class BodyAsyncIterable {
18
+ constructor (body) {
19
+ this[kBody] = body
20
+ this[kBodyUsed] = false
21
+ }
22
+
23
+ async * [Symbol.asyncIterator] () {
24
+ assert(!this[kBodyUsed], 'disturbed')
25
+ this[kBodyUsed] = true
26
+ yield * this[kBody]
27
+ }
28
+ }
29
+
30
+ function noop () {}
31
+
32
+ /**
33
+ * @param {*} body
34
+ * @returns {*}
35
+ */
36
+ function wrapRequestBody (body) {
37
+ if (isStream(body)) {
38
+ // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
39
+ // so that it can be dispatched again?
40
+ // TODO (fix): Do we need 100-expect support to provide a way to do this properly?
41
+ if (bodyLength(body) === 0) {
42
+ body
43
+ .on('data', function () {
44
+ assert(false)
45
+ })
46
+ }
47
+
48
+ if (typeof body.readableDidRead !== 'boolean') {
49
+ body[kBodyUsed] = false
50
+ EE.prototype.on.call(body, 'data', function () {
51
+ this[kBodyUsed] = true
52
+ })
53
+ }
54
+
55
+ return body
56
+ } else if (body && typeof body.pipeTo === 'function') {
57
+ // TODO (fix): We can't access ReadableStream internal state
58
+ // to determine whether or not it has been disturbed. This is just
59
+ // a workaround.
60
+ return new BodyAsyncIterable(body)
61
+ } else if (body && isFormDataLike(body)) {
62
+ return body
63
+ } else if (
64
+ body &&
65
+ typeof body !== 'string' &&
66
+ !ArrayBuffer.isView(body) &&
67
+ isIterable(body)
68
+ ) {
69
+ // TODO: Should we allow re-using iterable if !this.opts.idempotent
70
+ // or through some other flag?
71
+ return new BodyAsyncIterable(body)
72
+ } else {
73
+ return body
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @param {*} obj
79
+ * @returns {obj is import('node:stream').Stream}
80
+ */
81
+ function isStream (obj) {
82
+ return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function'
83
+ }
84
+
85
+ /**
86
+ * @param {*} object
87
+ * @returns {object is Blob}
88
+ * based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License)
89
+ */
90
+ function isBlobLike (object) {
91
+ if (object === null) {
92
+ return false
93
+ } else if (object instanceof Blob) {
94
+ return true
95
+ } else if (typeof object !== 'object') {
96
+ return false
97
+ } else {
98
+ const sTag = object[Symbol.toStringTag]
99
+
100
+ return (sTag === 'Blob' || sTag === 'File') && (
101
+ ('stream' in object && typeof object.stream === 'function') ||
102
+ ('arrayBuffer' in object && typeof object.arrayBuffer === 'function')
103
+ )
104
+ }
105
+ }
106
+
107
+ /**
108
+ * @param {string} url The path to check for query strings or fragments.
109
+ * @returns {boolean} Returns true if the path contains a query string or fragment.
110
+ */
111
+ function pathHasQueryOrFragment (url) {
112
+ return (
113
+ url.includes('?') ||
114
+ url.includes('#')
115
+ )
116
+ }
117
+
118
+ /**
119
+ * @param {string} url The URL to add the query params to
120
+ * @param {import('node:querystring').ParsedUrlQueryInput} queryParams The object to serialize into a URL query string
121
+ * @returns {string} The URL with the query params added
122
+ */
123
+ function serializePathWithQuery (url, queryParams) {
124
+ if (pathHasQueryOrFragment(url)) {
125
+ throw new Error('Query params cannot be passed when url already contains "?" or "#".')
126
+ }
127
+
128
+ const stringified = stringify(queryParams)
129
+
130
+ if (stringified) {
131
+ url += '?' + stringified
132
+ }
133
+
134
+ return url
135
+ }
136
+
137
+ /**
138
+ * @param {number|string|undefined} port
139
+ * @returns {boolean}
140
+ */
141
+ function isValidPort (port) {
142
+ const value = parseInt(port, 10)
143
+ return (
144
+ value === Number(port) &&
145
+ value >= 0 &&
146
+ value <= 65535
147
+ )
148
+ }
149
+
150
+ /**
151
+ * Check if the value is a valid http or https prefixed string.
152
+ *
153
+ * @param {string} value
154
+ * @returns {boolean}
155
+ */
156
+ function isHttpOrHttpsPrefixed (value) {
157
+ return (
158
+ value != null &&
159
+ value[0] === 'h' &&
160
+ value[1] === 't' &&
161
+ value[2] === 't' &&
162
+ value[3] === 'p' &&
163
+ (
164
+ value[4] === ':' ||
165
+ (
166
+ value[4] === 's' &&
167
+ value[5] === ':'
168
+ )
169
+ )
170
+ )
171
+ }
172
+
173
+ /**
174
+ * @param {string|URL|Record<string,string>} url
175
+ * @returns {URL}
176
+ */
177
+ function parseURL (url) {
178
+ if (typeof url === 'string') {
179
+ /**
180
+ * @type {URL}
181
+ */
182
+ url = new URL(url)
183
+
184
+ if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
185
+ throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
186
+ }
187
+
188
+ return url
189
+ }
190
+
191
+ if (!url || typeof url !== 'object') {
192
+ throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.')
193
+ }
194
+
195
+ if (!(url instanceof URL)) {
196
+ if (url.port != null && url.port !== '' && isValidPort(url.port) === false) {
197
+ throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.')
198
+ }
199
+
200
+ if (url.path != null && typeof url.path !== 'string') {
201
+ throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.')
202
+ }
203
+
204
+ if (url.pathname != null && typeof url.pathname !== 'string') {
205
+ throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.')
206
+ }
207
+
208
+ if (url.hostname != null && typeof url.hostname !== 'string') {
209
+ throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.')
210
+ }
211
+
212
+ if (url.origin != null && typeof url.origin !== 'string') {
213
+ throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.')
214
+ }
215
+
216
+ if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
217
+ throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
218
+ }
219
+
220
+ const port = url.port != null
221
+ ? url.port
222
+ : (url.protocol === 'https:' ? 443 : 80)
223
+ let origin = url.origin != null
224
+ ? url.origin
225
+ : `${url.protocol || ''}//${url.hostname || ''}:${port}`
226
+ let path = url.path != null
227
+ ? url.path
228
+ : `${url.pathname || ''}${url.search || ''}`
229
+
230
+ if (origin[origin.length - 1] === '/') {
231
+ origin = origin.slice(0, origin.length - 1)
232
+ }
233
+
234
+ if (path && path[0] !== '/') {
235
+ path = `/${path}`
236
+ }
237
+ // new URL(path, origin) is unsafe when `path` contains an absolute URL
238
+ // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL:
239
+ // If first parameter is a relative URL, second param is required, and will be used as the base URL.
240
+ // If first parameter is an absolute URL, a given second param will be ignored.
241
+ return new URL(`${origin}${path}`)
242
+ }
243
+
244
+ if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
245
+ throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
246
+ }
247
+
248
+ return url
249
+ }
250
+
251
+ /**
252
+ * @param {string|URL|Record<string, string>} url
253
+ * @returns {URL}
254
+ */
255
+ function parseOrigin (url) {
256
+ url = parseURL(url)
257
+
258
+ if (url.pathname !== '/' || url.search || url.hash) {
259
+ throw new InvalidArgumentError('invalid url')
260
+ }
261
+
262
+ return url
263
+ }
264
+
265
+ /**
266
+ * @param {string} host
267
+ * @returns {string}
268
+ */
269
+ function getHostname (host) {
270
+ if (host[0] === '[') {
271
+ const idx = host.indexOf(']')
272
+
273
+ assert(idx !== -1)
274
+ return host.substring(1, idx)
275
+ }
276
+
277
+ const idx = host.indexOf(':')
278
+ if (idx === -1) return host
279
+
280
+ return host.substring(0, idx)
281
+ }
282
+
283
+ /**
284
+ * IP addresses are not valid server names per RFC6066
285
+ * Currently, the only server names supported are DNS hostnames
286
+ * @param {string|null} host
287
+ * @returns {string|null}
288
+ */
289
+ function getServerName (host) {
290
+ if (!host) {
291
+ return null
292
+ }
293
+
294
+ assert(typeof host === 'string')
295
+
296
+ const servername = getHostname(host)
297
+ if (net.isIP(servername)) {
298
+ return ''
299
+ }
300
+
301
+ return servername
302
+ }
303
+
304
+ /**
305
+ * @function
306
+ * @template T
307
+ * @param {T} obj
308
+ * @returns {T}
309
+ */
310
+ function deepClone (obj) {
311
+ return JSON.parse(JSON.stringify(obj))
312
+ }
313
+
314
+ /**
315
+ * @param {*} obj
316
+ * @returns {obj is AsyncIterable}
317
+ */
318
+ function isAsyncIterable (obj) {
319
+ return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function')
320
+ }
321
+
322
+ /**
323
+ * @param {*} obj
324
+ * @returns {obj is Iterable}
325
+ */
326
+ function isIterable (obj) {
327
+ return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function'))
328
+ }
329
+
330
+ /**
331
+ * Checks whether an object has a safe Symbol.iterator — i.e. one that is
332
+ * either own or inherited from a non-Object.prototype chain. This prevents
333
+ * prototype-pollution attacks from injecting a fake iterator on
334
+ * Object.prototype.
335
+ * @param {object} obj
336
+ * @returns {boolean}
337
+ */
338
+ function hasSafeIterator (obj) {
339
+ const prototype = Object.getPrototypeOf(obj)
340
+ const ownIterator = Object.prototype.hasOwnProperty.call(obj, Symbol.iterator)
341
+ return ownIterator || (prototype != null && prototype !== Object.prototype && typeof obj[Symbol.iterator] === 'function')
342
+ }
343
+
344
+ /**
345
+ * @param {Blob|Buffer|import ('stream').Stream} body
346
+ * @returns {number|null}
347
+ */
348
+ function bodyLength (body) {
349
+ if (body == null) {
350
+ return 0
351
+ } else if (isStream(body)) {
352
+ const state = body._readableState
353
+ return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length)
354
+ ? state.length
355
+ : null
356
+ } else if (isBlobLike(body)) {
357
+ return body.size != null ? body.size : null
358
+ } else if (isBuffer(body)) {
359
+ return body.byteLength
360
+ }
361
+
362
+ return null
363
+ }
364
+
365
+ /**
366
+ * @param {import ('stream').Stream} body
367
+ * @returns {boolean}
368
+ */
369
+ function isDestroyed (body) {
370
+ return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body)))
371
+ }
372
+
373
+ /**
374
+ * @param {import ('stream').Stream} stream
375
+ * @param {Error} [err]
376
+ * @returns {void}
377
+ */
378
+ function destroy (stream, err) {
379
+ if (stream == null || !isStream(stream) || isDestroyed(stream)) {
380
+ return
381
+ }
382
+
383
+ if (typeof stream.destroy === 'function') {
384
+ if (Object.getPrototypeOf(stream).constructor === IncomingMessage) {
385
+ // See: https://github.com/nodejs/node/pull/38505/files
386
+ stream.socket = null
387
+ }
388
+
389
+ stream.destroy(err)
390
+ } else if (err) {
391
+ queueMicrotask(() => {
392
+ stream.emit('error', err)
393
+ })
394
+ }
395
+
396
+ if (stream.destroyed !== true) {
397
+ stream[kDestroyed] = true
398
+ }
399
+ }
400
+
401
+ const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/
402
+ /**
403
+ * @param {string} val
404
+ * @returns {number | null}
405
+ */
406
+ function parseKeepAliveTimeout (val) {
407
+ const m = val.match(KEEPALIVE_TIMEOUT_EXPR)
408
+ return m ? parseInt(m[1], 10) * 1000 : null
409
+ }
410
+
411
+ /**
412
+ * Retrieves a header name and returns its lowercase value.
413
+ * @param {string | Buffer} value Header name
414
+ * @returns {string}
415
+ */
416
+ function headerNameToString (value) {
417
+ return typeof value === 'string'
418
+ ? headerNameLowerCasedRecord[value] ?? value.toLowerCase()
419
+ : tree.lookup(value) ?? value.toString('latin1').toLowerCase()
420
+ }
421
+
422
+ /**
423
+ * Receive the buffer as a string and return its lowercase value.
424
+ * @param {Buffer} value Header name
425
+ * @returns {string}
426
+ */
427
+ function bufferToLowerCasedHeaderName (value) {
428
+ return tree.lookup(value) ?? value.toString('latin1').toLowerCase()
429
+ }
430
+
431
+ /**
432
+ * @param {(Buffer | string)[]} headers
433
+ * @param {Record<string, string | string[]>} [obj]
434
+ * @returns {Record<string, string | string[]>}
435
+ */
436
+ function parseHeaders (headers, obj) {
437
+ if (obj === undefined) obj = {}
438
+
439
+ for (let i = 0; i < headers.length; i += 2) {
440
+ const key = headerNameToString(headers[i])
441
+ let val = obj[key]
442
+
443
+ if (val !== undefined) {
444
+ if (!Object.hasOwn(obj, key)) {
445
+ const headersValue = typeof headers[i + 1] === 'string'
446
+ ? headers[i + 1]
447
+ : Array.isArray(headers[i + 1])
448
+ ? headers[i + 1].map(x => x.toString('latin1'))
449
+ : headers[i + 1].toString('latin1')
450
+
451
+ if (key === '__proto__') {
452
+ Object.defineProperty(obj, key, {
453
+ value: headersValue,
454
+ enumerable: true,
455
+ configurable: true,
456
+ writable: true
457
+ })
458
+ } else {
459
+ obj[key] = headersValue
460
+ }
461
+ } else {
462
+ if (typeof val === 'string') {
463
+ val = [val]
464
+ obj[key] = val
465
+ }
466
+ val.push(headers[i + 1].toString('latin1'))
467
+ }
468
+ } else {
469
+ const headersValue = typeof headers[i + 1] === 'string'
470
+ ? headers[i + 1]
471
+ : Array.isArray(headers[i + 1])
472
+ ? headers[i + 1].map(x => x.toString('latin1'))
473
+ : headers[i + 1].toString('latin1')
474
+
475
+ obj[key] = headersValue
476
+ }
477
+ }
478
+
479
+ return obj
480
+ }
481
+
482
+ /**
483
+ * @param {Buffer[]} headers
484
+ * @returns {string[]}
485
+ */
486
+ function parseRawHeaders (headers) {
487
+ const headersLength = headers.length
488
+ /**
489
+ * @type {string[]}
490
+ */
491
+ const ret = new Array(headersLength)
492
+
493
+ let key
494
+ let val
495
+
496
+ for (let n = 0; n < headersLength; n += 2) {
497
+ key = headers[n]
498
+ val = headers[n + 1]
499
+
500
+ typeof key !== 'string' && (key = key.toString())
501
+ typeof val !== 'string' && (val = val.toString('latin1'))
502
+
503
+ ret[n] = key
504
+ ret[n + 1] = val
505
+ }
506
+
507
+ return ret
508
+ }
509
+
510
+ /**
511
+ * @param {string[]} headers
512
+ * @param {Buffer[]} headers
513
+ */
514
+ function encodeRawHeaders (headers) {
515
+ if (!Array.isArray(headers)) {
516
+ throw new TypeError('expected headers to be an array')
517
+ }
518
+ return headers.map(x => Buffer.from(x))
519
+ }
520
+
521
+ /**
522
+ * @param {*} buffer
523
+ * @returns {buffer is Buffer}
524
+ */
525
+ function isBuffer (buffer) {
526
+ // See, https://github.com/mcollina/undici/pull/319
527
+ return buffer instanceof Uint8Array || Buffer.isBuffer(buffer)
528
+ }
529
+
530
+ /**
531
+ * Asserts that the handler object is a request handler.
532
+ *
533
+ * @param {object} handler
534
+ * @param {string} method
535
+ * @param {string} [upgrade]
536
+ * @returns {asserts handler is import('../api/api-request').RequestHandler}
537
+ */
538
+ function assertRequestHandler (handler, method, upgrade) {
539
+ if (!handler || typeof handler !== 'object') {
540
+ throw new InvalidArgumentError('handler must be an object')
541
+ }
542
+
543
+ if (typeof handler.onRequestStart === 'function') {
544
+ // TODO (fix): More checks...
545
+ return
546
+ }
547
+
548
+ if (typeof handler.onConnect !== 'function') {
549
+ throw new InvalidArgumentError('invalid onConnect method')
550
+ }
551
+
552
+ if (typeof handler.onError !== 'function') {
553
+ throw new InvalidArgumentError('invalid onError method')
554
+ }
555
+
556
+ if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) {
557
+ throw new InvalidArgumentError('invalid onBodySent method')
558
+ }
559
+
560
+ if (upgrade || method === 'CONNECT') {
561
+ if (typeof handler.onUpgrade !== 'function') {
562
+ throw new InvalidArgumentError('invalid onUpgrade method')
563
+ }
564
+ } else {
565
+ if (typeof handler.onHeaders !== 'function') {
566
+ throw new InvalidArgumentError('invalid onHeaders method')
567
+ }
568
+
569
+ if (typeof handler.onData !== 'function') {
570
+ throw new InvalidArgumentError('invalid onData method')
571
+ }
572
+
573
+ if (typeof handler.onComplete !== 'function') {
574
+ throw new InvalidArgumentError('invalid onComplete method')
575
+ }
576
+ }
577
+ }
578
+
579
+ /**
580
+ * A body is disturbed if it has been read from and it cannot be re-used without
581
+ * losing state or data.
582
+ * @param {import('node:stream').Readable} body
583
+ * @returns {boolean}
584
+ */
585
+ function isDisturbed (body) {
586
+ // TODO (fix): Why is body[kBodyUsed] needed?
587
+ return !!(body && (stream.isDisturbed(body) || body[kBodyUsed]))
588
+ }
589
+
590
+ /**
591
+ * @typedef {object} SocketInfo
592
+ * @property {string} [localAddress]
593
+ * @property {number} [localPort]
594
+ * @property {string} [remoteAddress]
595
+ * @property {number} [remotePort]
596
+ * @property {string} [remoteFamily]
597
+ * @property {number} [timeout]
598
+ * @property {number} bytesWritten
599
+ * @property {number} bytesRead
600
+ */
601
+
602
+ /**
603
+ * @param {import('net').Socket} socket
604
+ * @returns {SocketInfo}
605
+ */
606
+ function getSocketInfo (socket) {
607
+ return {
608
+ localAddress: socket.localAddress,
609
+ localPort: socket.localPort,
610
+ remoteAddress: socket.remoteAddress,
611
+ remotePort: socket.remotePort,
612
+ remoteFamily: socket.remoteFamily,
613
+ timeout: socket.timeout,
614
+ bytesWritten: socket.bytesWritten,
615
+ bytesRead: socket.bytesRead
616
+ }
617
+ }
618
+
619
+ /**
620
+ * @param {Iterable} iterable
621
+ * @returns {ReadableStream}
622
+ */
623
+ function ReadableStreamFrom (iterable) {
624
+ // We cannot use ReadableStream.from here because it does not return a byte stream.
625
+
626
+ let iterator
627
+ return new ReadableStream(
628
+ {
629
+ start () {
630
+ iterator = iterable[Symbol.asyncIterator]()
631
+ },
632
+ pull (controller) {
633
+ return iterator.next().then(({ done, value }) => {
634
+ if (done) {
635
+ return queueMicrotask(() => {
636
+ controller.close()
637
+ controller.byobRequest?.respond(0)
638
+ })
639
+ } else {
640
+ const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
641
+ if (buf.byteLength) {
642
+ return controller.enqueue(new Uint8Array(buf))
643
+ } else {
644
+ return this.pull(controller)
645
+ }
646
+ }
647
+ })
648
+ },
649
+ cancel () {
650
+ return iterator.return()
651
+ },
652
+ type: 'bytes'
653
+ }
654
+ )
655
+ }
656
+
657
+ /**
658
+ * The object should be a FormData instance and contains all the required
659
+ * methods.
660
+ * @param {*} object
661
+ * @returns {object is FormData}
662
+ */
663
+ function isFormDataLike (object) {
664
+ return (
665
+ object &&
666
+ typeof object === 'object' &&
667
+ typeof object.append === 'function' &&
668
+ typeof object.delete === 'function' &&
669
+ typeof object.get === 'function' &&
670
+ typeof object.getAll === 'function' &&
671
+ typeof object.has === 'function' &&
672
+ typeof object.set === 'function' &&
673
+ object[Symbol.toStringTag] === 'FormData'
674
+ )
675
+ }
676
+
677
+ function addAbortListener (signal, listener) {
678
+ if ('addEventListener' in signal) {
679
+ signal.addEventListener('abort', listener, { once: true })
680
+ return () => signal.removeEventListener('abort', listener)
681
+ }
682
+ signal.once('abort', listener)
683
+ return () => signal.removeListener('abort', listener)
684
+ }
685
+
686
+ const validTokenChars = new Uint8Array([
687
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
688
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
689
+ 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32-47 (!"#$%&'()*+,-./)
690
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 (0-9:;<=>?)
691
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79 (@A-O)
692
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80-95 (P-Z[\]^_)
693
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111 (`a-o)
694
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112-127 (p-z{|}~)
695
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-143
696
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144-159
697
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-175
698
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 176-191
699
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 192-207
700
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 208-223
701
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 224-239
702
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 240-255
703
+ ])
704
+
705
+ /**
706
+ * @see https://tools.ietf.org/html/rfc7230#section-3.2.6
707
+ * @param {number} c
708
+ * @returns {boolean}
709
+ */
710
+ function isTokenCharCode (c) {
711
+ return (validTokenChars[c] === 1)
712
+ }
713
+
714
+ const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/
715
+
716
+ /**
717
+ * @param {string} characters
718
+ * @returns {boolean}
719
+ */
720
+ function isValidHTTPToken (characters) {
721
+ if (characters.length >= 12) return tokenRegExp.test(characters)
722
+ if (characters.length === 0) return false
723
+
724
+ for (let i = 0; i < characters.length; i++) {
725
+ if (validTokenChars[characters.charCodeAt(i)] !== 1) {
726
+ return false
727
+ }
728
+ }
729
+ return true
730
+ }
731
+
732
+ // headerCharRegex have been lifted from
733
+ // https://github.com/nodejs/node/blob/main/lib/_http_common.js
734
+
735
+ /**
736
+ * Matches if val contains an invalid field-vchar
737
+ * field-value = *( field-content / obs-fold )
738
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
739
+ * field-vchar = VCHAR / obs-text
740
+ */
741
+ const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/
742
+
743
+ /**
744
+ * @param {string} characters
745
+ * @returns {boolean}
746
+ */
747
+ function isValidHeaderValue (characters) {
748
+ return !headerCharRegex.test(characters)
749
+ }
750
+
751
+ const rangeHeaderRegex = /^bytes (\d+)-(\d+)\/(\d+)?$/
752
+
753
+ /**
754
+ * @typedef {object} RangeHeader
755
+ * @property {number} start
756
+ * @property {number | null} end
757
+ * @property {number | null} size
758
+ */
759
+
760
+ /**
761
+ * Parse accordingly to RFC 9110
762
+ * @see https://www.rfc-editor.org/rfc/rfc9110#field.content-range
763
+ * @param {string} [range]
764
+ * @returns {RangeHeader|null}
765
+ */
766
+ function parseRangeHeader (range) {
767
+ if (range == null || range === '') return { start: 0, end: null, size: null }
768
+
769
+ const m = range ? range.match(rangeHeaderRegex) : null
770
+ return m
771
+ ? {
772
+ start: parseInt(m[1]),
773
+ end: m[2] ? parseInt(m[2]) : null,
774
+ size: m[3] ? parseInt(m[3]) : null
775
+ }
776
+ : null
777
+ }
778
+
779
+ /**
780
+ * @template {import("events").EventEmitter} T
781
+ * @param {T} obj
782
+ * @param {string} name
783
+ * @param {(...args: any[]) => void} listener
784
+ * @returns {T}
785
+ */
786
+ function addListener (obj, name, listener) {
787
+ const listeners = (obj[kListeners] ??= [])
788
+ listeners.push([name, listener])
789
+ obj.on(name, listener)
790
+ return obj
791
+ }
792
+
793
+ /**
794
+ * @template {import("events").EventEmitter} T
795
+ * @param {T} obj
796
+ * @returns {T}
797
+ */
798
+ function removeAllListeners (obj) {
799
+ if (obj[kListeners] != null) {
800
+ for (const [name, listener] of obj[kListeners]) {
801
+ obj.removeListener(name, listener)
802
+ }
803
+ obj[kListeners] = null
804
+ }
805
+ return obj
806
+ }
807
+
808
+ /**
809
+ * @param {import ('../dispatcher/client')} client
810
+ * @param {import ('../core/request')} request
811
+ * @param {Error} err
812
+ */
813
+ function errorRequest (client, request, err) {
814
+ try {
815
+ request.onError(err)
816
+ assert(request.aborted)
817
+ } catch (err) {
818
+ client.emit('error', err)
819
+ }
820
+ }
821
+
822
+ /**
823
+ * @param {WeakRef<net.Socket>} socketWeakRef
824
+ * @param {object} opts
825
+ * @param {number} opts.timeout
826
+ * @param {string} opts.hostname
827
+ * @param {number} opts.port
828
+ * @returns {() => void}
829
+ */
830
+ const setupConnectTimeout = process.platform === 'win32'
831
+ ? (socketWeakRef, opts) => {
832
+ if (!opts.timeout) {
833
+ return noop
834
+ }
835
+
836
+ let s1 = null
837
+ let s2 = null
838
+ const fastTimer = timers.setFastTimeout(() => {
839
+ // setImmediate is added to make sure that we prioritize socket error events over timeouts
840
+ s1 = setImmediate(() => {
841
+ // Windows needs an extra setImmediate probably due to implementation differences in the socket logic
842
+ s2 = setImmediate(() => onConnectTimeout(socketWeakRef.deref(), opts))
843
+ })
844
+ }, opts.timeout)
845
+ return () => {
846
+ timers.clearFastTimeout(fastTimer)
847
+ clearImmediate(s1)
848
+ clearImmediate(s2)
849
+ }
850
+ }
851
+ : (socketWeakRef, opts) => {
852
+ if (!opts.timeout) {
853
+ return noop
854
+ }
855
+
856
+ let s1 = null
857
+ const fastTimer = timers.setFastTimeout(() => {
858
+ // setImmediate is added to make sure that we prioritize socket error events over timeouts
859
+ s1 = setImmediate(() => {
860
+ onConnectTimeout(socketWeakRef.deref(), opts)
861
+ })
862
+ }, opts.timeout)
863
+ return () => {
864
+ timers.clearFastTimeout(fastTimer)
865
+ clearImmediate(s1)
866
+ }
867
+ }
868
+
869
+ /**
870
+ * @param {net.Socket} socket
871
+ * @param {object} opts
872
+ * @param {number} opts.timeout
873
+ * @param {string} opts.hostname
874
+ * @param {number} opts.port
875
+ */
876
+ function onConnectTimeout (socket, opts) {
877
+ // The socket could be already garbage collected
878
+ if (socket == null) {
879
+ return
880
+ }
881
+
882
+ let message = 'Connect Timeout Error'
883
+ if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) {
884
+ message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},`
885
+ } else {
886
+ message += ` (attempted address: ${opts.hostname}:${opts.port},`
887
+ }
888
+
889
+ message += ` timeout: ${opts.timeout}ms)`
890
+
891
+ destroy(socket, new ConnectTimeoutError(message))
892
+ }
893
+
894
+ /**
895
+ * @param {string} urlString
896
+ * @returns {string}
897
+ */
898
+ function getProtocolFromUrlString (urlString) {
899
+ if (
900
+ urlString[0] === 'h' &&
901
+ urlString[1] === 't' &&
902
+ urlString[2] === 't' &&
903
+ urlString[3] === 'p'
904
+ ) {
905
+ switch (urlString[4]) {
906
+ case ':':
907
+ return 'http:'
908
+ case 's':
909
+ if (urlString[5] === ':') {
910
+ return 'https:'
911
+ }
912
+ }
913
+ }
914
+ // fallback if none of the usual suspects
915
+ return urlString.slice(0, urlString.indexOf(':') + 1)
916
+ }
917
+
918
+ const kEnumerableProperty = Object.create(null)
919
+ kEnumerableProperty.enumerable = true
920
+
921
+ const normalizedMethodRecordsBase = {
922
+ delete: 'DELETE',
923
+ DELETE: 'DELETE',
924
+ get: 'GET',
925
+ GET: 'GET',
926
+ head: 'HEAD',
927
+ HEAD: 'HEAD',
928
+ options: 'OPTIONS',
929
+ OPTIONS: 'OPTIONS',
930
+ post: 'POST',
931
+ POST: 'POST',
932
+ put: 'PUT',
933
+ PUT: 'PUT'
934
+ }
935
+
936
+ const normalizedMethodRecords = {
937
+ ...normalizedMethodRecordsBase,
938
+ patch: 'patch',
939
+ PATCH: 'PATCH'
940
+ }
941
+
942
+ // Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
943
+ Object.setPrototypeOf(normalizedMethodRecordsBase, null)
944
+ Object.setPrototypeOf(normalizedMethodRecords, null)
945
+
946
+ module.exports = {
947
+ kEnumerableProperty,
948
+ isDisturbed,
949
+ isBlobLike,
950
+ parseOrigin,
951
+ parseURL,
952
+ getServerName,
953
+ isStream,
954
+ isIterable,
955
+ hasSafeIterator,
956
+ isAsyncIterable,
957
+ isDestroyed,
958
+ headerNameToString,
959
+ bufferToLowerCasedHeaderName,
960
+ addListener,
961
+ removeAllListeners,
962
+ errorRequest,
963
+ parseRawHeaders,
964
+ encodeRawHeaders,
965
+ parseHeaders,
966
+ parseKeepAliveTimeout,
967
+ destroy,
968
+ bodyLength,
969
+ deepClone,
970
+ ReadableStreamFrom,
971
+ isBuffer,
972
+ assertRequestHandler,
973
+ getSocketInfo,
974
+ isFormDataLike,
975
+ pathHasQueryOrFragment,
976
+ serializePathWithQuery,
977
+ addAbortListener,
978
+ isValidHTTPToken,
979
+ isValidHeaderValue,
980
+ isTokenCharCode,
981
+ parseRangeHeader,
982
+ normalizedMethodRecordsBase,
983
+ normalizedMethodRecords,
984
+ isValidPort,
985
+ isHttpOrHttpsPrefixed,
986
+ nodeMajor,
987
+ nodeMinor,
988
+ safeHTTPMethods: Object.freeze(['GET', 'HEAD', 'OPTIONS', 'TRACE']),
989
+ wrapRequestBody,
990
+ setupConnectTimeout,
991
+ getProtocolFromUrlString
992
+ }