@pnpm/exe 11.0.5 → 11.0.7

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 (381) hide show
  1. package/dist/node-gyp-bin/node-gyp +0 -0
  2. package/dist/node-gyp-bin/node-gyp.cmd +0 -0
  3. package/dist/node_modules/node-gyp/.release-please-manifest.json +1 -1
  4. package/dist/node_modules/node-gyp/bin/node-gyp.js +0 -0
  5. package/dist/node_modules/node-gyp/gyp/.release-please-manifest.json +1 -1
  6. package/dist/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +11 -3
  7. package/dist/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +2 -3
  8. package/dist/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +1 -1
  9. package/dist/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +2 -1
  10. package/dist/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +26 -16
  11. package/dist/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +1 -1
  12. package/dist/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +1 -1
  13. package/dist/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +2 -2
  14. package/dist/node_modules/node-gyp/gyp/pylib/packaging/metadata.py +3 -20
  15. package/dist/node_modules/node-gyp/gyp/pylib/packaging/tags.py +2 -14
  16. package/dist/node_modules/node-gyp/gyp/pyproject.toml +5 -3
  17. package/dist/node_modules/node-gyp/lib/download.js +55 -8
  18. package/dist/node_modules/node-gyp/lib/find-visualstudio.js +1 -1
  19. package/dist/node_modules/node-gyp/lib/process-release.js +17 -19
  20. package/dist/node_modules/node-gyp/package.json +3 -3
  21. package/dist/node_modules/{safer-buffer → undici}/LICENSE +1 -1
  22. package/dist/node_modules/undici/index-fetch.js +35 -0
  23. package/dist/node_modules/undici/index.js +169 -0
  24. package/dist/node_modules/undici/lib/api/abort-signal.js +57 -0
  25. package/dist/node_modules/undici/lib/api/api-connect.js +108 -0
  26. package/dist/node_modules/undici/lib/api/api-pipeline.js +251 -0
  27. package/dist/node_modules/undici/lib/api/api-request.js +214 -0
  28. package/dist/node_modules/undici/lib/api/api-stream.js +220 -0
  29. package/dist/node_modules/undici/lib/api/api-upgrade.js +108 -0
  30. package/dist/node_modules/undici/lib/api/index.js +7 -0
  31. package/dist/node_modules/undici/lib/api/readable.js +385 -0
  32. package/dist/node_modules/undici/lib/api/util.js +93 -0
  33. package/dist/node_modules/undici/lib/core/connect.js +240 -0
  34. package/dist/node_modules/undici/lib/core/constants.js +118 -0
  35. package/dist/node_modules/undici/lib/core/diagnostics.js +202 -0
  36. package/dist/node_modules/undici/lib/core/errors.js +425 -0
  37. package/dist/node_modules/undici/lib/core/request.js +405 -0
  38. package/dist/node_modules/undici/lib/core/symbols.js +67 -0
  39. package/dist/node_modules/undici/lib/core/tree.js +152 -0
  40. package/dist/node_modules/undici/lib/core/util.js +719 -0
  41. package/dist/node_modules/undici/lib/dispatcher/agent.js +130 -0
  42. package/dist/node_modules/undici/lib/dispatcher/balanced-pool.js +209 -0
  43. package/dist/node_modules/undici/lib/dispatcher/client-h1.js +1370 -0
  44. package/dist/node_modules/undici/lib/dispatcher/client-h2.js +744 -0
  45. package/dist/node_modules/undici/lib/dispatcher/client.js +623 -0
  46. package/dist/node_modules/undici/lib/dispatcher/dispatcher-base.js +198 -0
  47. package/dist/node_modules/undici/lib/dispatcher/dispatcher.js +65 -0
  48. package/dist/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +160 -0
  49. package/dist/node_modules/undici/lib/dispatcher/fixed-queue.js +117 -0
  50. package/dist/node_modules/undici/lib/dispatcher/pool-base.js +194 -0
  51. package/dist/node_modules/undici/lib/dispatcher/pool-stats.js +34 -0
  52. package/dist/node_modules/undici/lib/dispatcher/pool.js +107 -0
  53. package/dist/node_modules/undici/lib/dispatcher/proxy-agent.js +274 -0
  54. package/dist/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  55. package/dist/node_modules/undici/lib/global.js +32 -0
  56. package/dist/node_modules/undici/lib/handler/decorator-handler.js +44 -0
  57. package/dist/node_modules/undici/lib/handler/redirect-handler.js +232 -0
  58. package/dist/node_modules/undici/lib/handler/retry-handler.js +374 -0
  59. package/dist/node_modules/undici/lib/interceptor/dns.js +375 -0
  60. package/dist/node_modules/undici/lib/interceptor/dump.js +123 -0
  61. package/dist/node_modules/undici/lib/interceptor/redirect-interceptor.js +21 -0
  62. package/dist/node_modules/undici/lib/interceptor/redirect.js +24 -0
  63. package/dist/node_modules/undici/lib/interceptor/response-error.js +86 -0
  64. package/dist/node_modules/undici/lib/interceptor/retry.js +19 -0
  65. package/dist/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  66. package/dist/node_modules/undici/lib/llhttp/constants.js +278 -0
  67. package/dist/node_modules/undici/lib/llhttp/llhttp-wasm.js +5 -0
  68. package/dist/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +5 -0
  69. package/dist/node_modules/undici/lib/llhttp/utils.js +15 -0
  70. package/dist/node_modules/undici/lib/mock/mock-agent.js +160 -0
  71. package/dist/node_modules/undici/lib/mock/mock-client.js +59 -0
  72. package/dist/node_modules/undici/lib/mock/mock-errors.js +28 -0
  73. package/dist/node_modules/undici/lib/mock/mock-interceptor.js +207 -0
  74. package/dist/node_modules/undici/lib/mock/mock-pool.js +59 -0
  75. package/dist/node_modules/undici/lib/mock/mock-symbols.js +23 -0
  76. package/dist/node_modules/undici/lib/mock/mock-utils.js +367 -0
  77. package/dist/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  78. package/dist/node_modules/undici/lib/mock/pluralizer.js +29 -0
  79. package/dist/node_modules/undici/lib/util/timers.js +423 -0
  80. package/dist/node_modules/undici/lib/web/cache/cache.js +859 -0
  81. package/dist/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  82. package/dist/node_modules/undici/lib/web/cache/symbols.js +5 -0
  83. package/dist/node_modules/undici/lib/web/cache/util.js +45 -0
  84. package/dist/node_modules/undici/lib/web/cookies/constants.js +12 -0
  85. package/dist/node_modules/undici/lib/web/cookies/index.js +184 -0
  86. package/dist/node_modules/undici/lib/web/cookies/parse.js +317 -0
  87. package/dist/node_modules/undici/lib/web/cookies/util.js +282 -0
  88. package/dist/node_modules/undici/lib/web/eventsource/eventsource-stream.js +398 -0
  89. package/dist/node_modules/undici/lib/web/eventsource/eventsource.js +480 -0
  90. package/dist/node_modules/undici/lib/web/eventsource/util.js +37 -0
  91. package/dist/node_modules/{@npmcli/redact → undici/lib/web/fetch}/LICENSE +1 -1
  92. package/dist/node_modules/undici/lib/web/fetch/body.js +529 -0
  93. package/dist/node_modules/undici/lib/web/fetch/constants.js +124 -0
  94. package/dist/node_modules/undici/lib/web/fetch/data-url.js +744 -0
  95. package/dist/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +46 -0
  96. package/dist/node_modules/undici/lib/web/fetch/file.js +126 -0
  97. package/dist/node_modules/undici/lib/web/fetch/formdata-parser.js +474 -0
  98. package/dist/node_modules/undici/lib/web/fetch/formdata.js +252 -0
  99. package/dist/node_modules/undici/lib/web/fetch/global.js +40 -0
  100. package/dist/node_modules/undici/lib/web/fetch/headers.js +687 -0
  101. package/dist/node_modules/undici/lib/web/fetch/index.js +2272 -0
  102. package/dist/node_modules/undici/lib/web/fetch/request.js +1037 -0
  103. package/dist/node_modules/undici/lib/web/fetch/response.js +610 -0
  104. package/dist/node_modules/undici/lib/web/fetch/symbols.js +9 -0
  105. package/dist/node_modules/undici/lib/web/fetch/util.js +1632 -0
  106. package/dist/node_modules/undici/lib/web/fetch/webidl.js +695 -0
  107. package/dist/node_modules/undici/lib/web/fileapi/encoding.js +290 -0
  108. package/dist/node_modules/undici/lib/web/fileapi/filereader.js +344 -0
  109. package/dist/node_modules/undici/lib/web/fileapi/progressevent.js +78 -0
  110. package/dist/node_modules/undici/lib/web/fileapi/symbols.js +10 -0
  111. package/dist/node_modules/undici/lib/web/fileapi/util.js +391 -0
  112. package/dist/node_modules/undici/lib/web/websocket/connection.js +371 -0
  113. package/dist/node_modules/undici/lib/web/websocket/constants.js +66 -0
  114. package/dist/node_modules/undici/lib/web/websocket/events.js +329 -0
  115. package/dist/node_modules/undici/lib/web/websocket/frame.js +96 -0
  116. package/dist/node_modules/undici/lib/web/websocket/permessage-deflate.js +100 -0
  117. package/dist/node_modules/undici/lib/web/websocket/receiver.js +490 -0
  118. package/dist/node_modules/undici/lib/web/websocket/sender.js +104 -0
  119. package/dist/node_modules/undici/lib/web/websocket/symbols.js +12 -0
  120. package/dist/node_modules/undici/lib/web/websocket/util.js +322 -0
  121. package/dist/node_modules/undici/lib/web/websocket/websocket.js +592 -0
  122. package/dist/node_modules/undici/package.json +160 -0
  123. package/dist/node_modules/undici/scripts/strip-comments.js +8 -0
  124. package/dist/node_modules/yallist/package.json +51 -12
  125. package/dist/pnpm.mjs +5915 -5140
  126. package/dist/worker.js +70 -67
  127. package/package.json +21 -13
  128. package/setup.js +17 -3
  129. package/dist/node_modules/@gar/promise-retry/LICENSE +0 -20
  130. package/dist/node_modules/@gar/promise-retry/lib/index.js +0 -62
  131. package/dist/node_modules/@gar/promise-retry/lib/retry.js +0 -109
  132. package/dist/node_modules/@gar/promise-retry/package.json +0 -45
  133. package/dist/node_modules/@npmcli/agent/lib/agents.js +0 -206
  134. package/dist/node_modules/@npmcli/agent/lib/dns.js +0 -53
  135. package/dist/node_modules/@npmcli/agent/lib/errors.js +0 -61
  136. package/dist/node_modules/@npmcli/agent/lib/index.js +0 -56
  137. package/dist/node_modules/@npmcli/agent/lib/options.js +0 -86
  138. package/dist/node_modules/@npmcli/agent/lib/proxy.js +0 -88
  139. package/dist/node_modules/@npmcli/agent/package.json +0 -60
  140. package/dist/node_modules/@npmcli/fs/lib/common/get-options.js +0 -20
  141. package/dist/node_modules/@npmcli/fs/lib/common/node.js +0 -9
  142. package/dist/node_modules/@npmcli/fs/lib/cp/LICENSE +0 -15
  143. package/dist/node_modules/@npmcli/fs/lib/cp/errors.js +0 -129
  144. package/dist/node_modules/@npmcli/fs/lib/cp/index.js +0 -22
  145. package/dist/node_modules/@npmcli/fs/lib/cp/polyfill.js +0 -428
  146. package/dist/node_modules/@npmcli/fs/lib/index.js +0 -13
  147. package/dist/node_modules/@npmcli/fs/lib/move-file.js +0 -78
  148. package/dist/node_modules/@npmcli/fs/lib/readdir-scoped.js +0 -20
  149. package/dist/node_modules/@npmcli/fs/lib/with-temp-dir.js +0 -39
  150. package/dist/node_modules/@npmcli/fs/package.json +0 -54
  151. package/dist/node_modules/@npmcli/redact/lib/deep-map.js +0 -71
  152. package/dist/node_modules/@npmcli/redact/lib/error.js +0 -28
  153. package/dist/node_modules/@npmcli/redact/lib/index.js +0 -44
  154. package/dist/node_modules/@npmcli/redact/lib/matchers.js +0 -88
  155. package/dist/node_modules/@npmcli/redact/lib/server.js +0 -59
  156. package/dist/node_modules/@npmcli/redact/lib/utils.js +0 -202
  157. package/dist/node_modules/@npmcli/redact/package.json +0 -52
  158. package/dist/node_modules/agent-base/LICENSE +0 -22
  159. package/dist/node_modules/agent-base/dist/helpers.js +0 -66
  160. package/dist/node_modules/agent-base/dist/index.js +0 -178
  161. package/dist/node_modules/agent-base/package.json +0 -46
  162. package/dist/node_modules/balanced-match/dist/commonjs/index.js +0 -59
  163. package/dist/node_modules/balanced-match/dist/esm/index.js +0 -54
  164. package/dist/node_modules/balanced-match/package.json +0 -68
  165. package/dist/node_modules/brace-expansion/LICENSE +0 -23
  166. package/dist/node_modules/brace-expansion/dist/commonjs/index.js +0 -201
  167. package/dist/node_modules/brace-expansion/dist/commonjs/package.json +0 -3
  168. package/dist/node_modules/brace-expansion/dist/esm/index.js +0 -197
  169. package/dist/node_modules/brace-expansion/dist/esm/package.json +0 -3
  170. package/dist/node_modules/brace-expansion/package.json +0 -64
  171. package/dist/node_modules/cacache/lib/content/path.js +0 -29
  172. package/dist/node_modules/cacache/lib/content/read.js +0 -165
  173. package/dist/node_modules/cacache/lib/content/rm.js +0 -18
  174. package/dist/node_modules/cacache/lib/content/write.js +0 -206
  175. package/dist/node_modules/cacache/lib/entry-index.js +0 -336
  176. package/dist/node_modules/cacache/lib/get.js +0 -170
  177. package/dist/node_modules/cacache/lib/index.js +0 -42
  178. package/dist/node_modules/cacache/lib/memoization.js +0 -72
  179. package/dist/node_modules/cacache/lib/put.js +0 -80
  180. package/dist/node_modules/cacache/lib/rm.js +0 -31
  181. package/dist/node_modules/cacache/lib/util/glob.js +0 -7
  182. package/dist/node_modules/cacache/lib/util/hash-to-segments.js +0 -7
  183. package/dist/node_modules/cacache/lib/util/tmp.js +0 -32
  184. package/dist/node_modules/cacache/lib/verify.js +0 -258
  185. package/dist/node_modules/cacache/package.json +0 -81
  186. package/dist/node_modules/debug/LICENSE +0 -20
  187. package/dist/node_modules/debug/package.json +0 -64
  188. package/dist/node_modules/debug/src/browser.js +0 -272
  189. package/dist/node_modules/debug/src/common.js +0 -292
  190. package/dist/node_modules/debug/src/index.js +0 -10
  191. package/dist/node_modules/debug/src/node.js +0 -263
  192. package/dist/node_modules/fs-minipass/LICENSE +0 -15
  193. package/dist/node_modules/fs-minipass/lib/index.js +0 -443
  194. package/dist/node_modules/fs-minipass/package.json +0 -54
  195. package/dist/node_modules/glob/dist/commonjs/glob.js +0 -248
  196. package/dist/node_modules/glob/dist/commonjs/has-magic.js +0 -27
  197. package/dist/node_modules/glob/dist/commonjs/ignore.js +0 -119
  198. package/dist/node_modules/glob/dist/commonjs/index.js +0 -68
  199. package/dist/node_modules/glob/dist/commonjs/index.min.js +0 -4
  200. package/dist/node_modules/glob/dist/commonjs/package.json +0 -3
  201. package/dist/node_modules/glob/dist/commonjs/pattern.js +0 -223
  202. package/dist/node_modules/glob/dist/commonjs/processor.js +0 -301
  203. package/dist/node_modules/glob/dist/commonjs/walker.js +0 -387
  204. package/dist/node_modules/glob/dist/esm/glob.js +0 -244
  205. package/dist/node_modules/glob/dist/esm/has-magic.js +0 -23
  206. package/dist/node_modules/glob/dist/esm/ignore.js +0 -115
  207. package/dist/node_modules/glob/dist/esm/index.js +0 -55
  208. package/dist/node_modules/glob/dist/esm/index.min.js +0 -4
  209. package/dist/node_modules/glob/dist/esm/package.json +0 -3
  210. package/dist/node_modules/glob/dist/esm/pattern.js +0 -219
  211. package/dist/node_modules/glob/dist/esm/processor.js +0 -294
  212. package/dist/node_modules/glob/dist/esm/walker.js +0 -381
  213. package/dist/node_modules/glob/package.json +0 -98
  214. package/dist/node_modules/http-cache-semantics/LICENSE +0 -9
  215. package/dist/node_modules/http-cache-semantics/index.js +0 -928
  216. package/dist/node_modules/http-cache-semantics/package.json +0 -22
  217. package/dist/node_modules/http-proxy-agent/LICENSE +0 -22
  218. package/dist/node_modules/http-proxy-agent/dist/index.js +0 -148
  219. package/dist/node_modules/http-proxy-agent/package.json +0 -47
  220. package/dist/node_modules/https-proxy-agent/LICENSE +0 -22
  221. package/dist/node_modules/https-proxy-agent/dist/index.js +0 -180
  222. package/dist/node_modules/https-proxy-agent/dist/parse-proxy-response.js +0 -101
  223. package/dist/node_modules/https-proxy-agent/package.json +0 -50
  224. package/dist/node_modules/iconv-lite/LICENSE +0 -21
  225. package/dist/node_modules/iconv-lite/encodings/dbcs-codec.js +0 -532
  226. package/dist/node_modules/iconv-lite/encodings/dbcs-data.js +0 -185
  227. package/dist/node_modules/iconv-lite/encodings/index.js +0 -23
  228. package/dist/node_modules/iconv-lite/encodings/internal.js +0 -218
  229. package/dist/node_modules/iconv-lite/encodings/sbcs-codec.js +0 -75
  230. package/dist/node_modules/iconv-lite/encodings/sbcs-data-generated.js +0 -451
  231. package/dist/node_modules/iconv-lite/encodings/sbcs-data.js +0 -178
  232. package/dist/node_modules/iconv-lite/encodings/tables/big5-added.json +0 -122
  233. package/dist/node_modules/iconv-lite/encodings/tables/cp936.json +0 -264
  234. package/dist/node_modules/iconv-lite/encodings/tables/cp949.json +0 -273
  235. package/dist/node_modules/iconv-lite/encodings/tables/cp950.json +0 -177
  236. package/dist/node_modules/iconv-lite/encodings/tables/eucjp.json +0 -182
  237. package/dist/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +0 -1
  238. package/dist/node_modules/iconv-lite/encodings/tables/gbk-added.json +0 -56
  239. package/dist/node_modules/iconv-lite/encodings/tables/shiftjis.json +0 -125
  240. package/dist/node_modules/iconv-lite/encodings/utf16.js +0 -187
  241. package/dist/node_modules/iconv-lite/encodings/utf32.js +0 -307
  242. package/dist/node_modules/iconv-lite/encodings/utf7.js +0 -283
  243. package/dist/node_modules/iconv-lite/lib/bom-handling.js +0 -48
  244. package/dist/node_modules/iconv-lite/lib/helpers/merge-exports.js +0 -13
  245. package/dist/node_modules/iconv-lite/lib/index.js +0 -182
  246. package/dist/node_modules/iconv-lite/lib/streams.js +0 -105
  247. package/dist/node_modules/iconv-lite/package.json +0 -70
  248. package/dist/node_modules/ip-address/LICENSE +0 -19
  249. package/dist/node_modules/ip-address/dist/address-error.js +0 -12
  250. package/dist/node_modules/ip-address/dist/common.js +0 -46
  251. package/dist/node_modules/ip-address/dist/ip-address.js +0 -35
  252. package/dist/node_modules/ip-address/dist/ipv4.js +0 -360
  253. package/dist/node_modules/ip-address/dist/ipv6.js +0 -1003
  254. package/dist/node_modules/ip-address/dist/v4/constants.js +0 -8
  255. package/dist/node_modules/ip-address/dist/v6/constants.js +0 -76
  256. package/dist/node_modules/ip-address/dist/v6/helpers.js +0 -45
  257. package/dist/node_modules/ip-address/dist/v6/regular-expressions.js +0 -95
  258. package/dist/node_modules/ip-address/package.json +0 -78
  259. package/dist/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +0 -10
  260. package/dist/node_modules/lru-cache/dist/commonjs/index.js +0 -1692
  261. package/dist/node_modules/lru-cache/dist/commonjs/index.min.js +0 -2
  262. package/dist/node_modules/lru-cache/dist/commonjs/package.json +0 -3
  263. package/dist/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +0 -4
  264. package/dist/node_modules/lru-cache/dist/esm/browser/index.js +0 -1688
  265. package/dist/node_modules/lru-cache/dist/esm/browser/index.min.js +0 -2
  266. package/dist/node_modules/lru-cache/dist/esm/diagnostics-channel.js +0 -19
  267. package/dist/node_modules/lru-cache/dist/esm/index.js +0 -1688
  268. package/dist/node_modules/lru-cache/dist/esm/index.min.js +0 -2
  269. package/dist/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +0 -7
  270. package/dist/node_modules/lru-cache/dist/esm/node/index.js +0 -1688
  271. package/dist/node_modules/lru-cache/dist/esm/node/index.min.js +0 -2
  272. package/dist/node_modules/lru-cache/dist/esm/package.json +0 -3
  273. package/dist/node_modules/lru-cache/package.json +0 -126
  274. package/dist/node_modules/make-fetch-happen/LICENSE +0 -16
  275. package/dist/node_modules/make-fetch-happen/lib/cache/entry.js +0 -471
  276. package/dist/node_modules/make-fetch-happen/lib/cache/errors.js +0 -11
  277. package/dist/node_modules/make-fetch-happen/lib/cache/index.js +0 -49
  278. package/dist/node_modules/make-fetch-happen/lib/cache/key.js +0 -17
  279. package/dist/node_modules/make-fetch-happen/lib/cache/policy.js +0 -161
  280. package/dist/node_modules/make-fetch-happen/lib/fetch.js +0 -118
  281. package/dist/node_modules/make-fetch-happen/lib/index.js +0 -41
  282. package/dist/node_modules/make-fetch-happen/lib/options.js +0 -59
  283. package/dist/node_modules/make-fetch-happen/lib/pipeline.js +0 -41
  284. package/dist/node_modules/make-fetch-happen/lib/remote.js +0 -134
  285. package/dist/node_modules/make-fetch-happen/package.json +0 -75
  286. package/dist/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +0 -14
  287. package/dist/node_modules/minimatch/dist/commonjs/ast.js +0 -845
  288. package/dist/node_modules/minimatch/dist/commonjs/brace-expressions.js +0 -150
  289. package/dist/node_modules/minimatch/dist/commonjs/escape.js +0 -30
  290. package/dist/node_modules/minimatch/dist/commonjs/index.js +0 -1127
  291. package/dist/node_modules/minimatch/dist/commonjs/package.json +0 -3
  292. package/dist/node_modules/minimatch/dist/commonjs/unescape.js +0 -38
  293. package/dist/node_modules/minimatch/dist/esm/assert-valid-pattern.js +0 -10
  294. package/dist/node_modules/minimatch/dist/esm/ast.js +0 -841
  295. package/dist/node_modules/minimatch/dist/esm/brace-expressions.js +0 -146
  296. package/dist/node_modules/minimatch/dist/esm/escape.js +0 -26
  297. package/dist/node_modules/minimatch/dist/esm/index.js +0 -1114
  298. package/dist/node_modules/minimatch/dist/esm/package.json +0 -3
  299. package/dist/node_modules/minimatch/dist/esm/unescape.js +0 -34
  300. package/dist/node_modules/minimatch/package.json +0 -73
  301. package/dist/node_modules/minipass-collect/LICENSE +0 -15
  302. package/dist/node_modules/minipass-collect/index.js +0 -71
  303. package/dist/node_modules/minipass-collect/package.json +0 -30
  304. package/dist/node_modules/minipass-fetch/LICENSE +0 -28
  305. package/dist/node_modules/minipass-fetch/lib/abort-error.js +0 -17
  306. package/dist/node_modules/minipass-fetch/lib/blob.js +0 -97
  307. package/dist/node_modules/minipass-fetch/lib/body.js +0 -360
  308. package/dist/node_modules/minipass-fetch/lib/fetch-error.js +0 -32
  309. package/dist/node_modules/minipass-fetch/lib/headers.js +0 -267
  310. package/dist/node_modules/minipass-fetch/lib/index.js +0 -376
  311. package/dist/node_modules/minipass-fetch/lib/request.js +0 -282
  312. package/dist/node_modules/minipass-fetch/lib/response.js +0 -90
  313. package/dist/node_modules/minipass-fetch/package.json +0 -70
  314. package/dist/node_modules/minipass-flush/index.js +0 -39
  315. package/dist/node_modules/minipass-flush/node_modules/minipass/LICENSE +0 -15
  316. package/dist/node_modules/minipass-flush/node_modules/minipass/index.js +0 -649
  317. package/dist/node_modules/minipass-flush/node_modules/minipass/package.json +0 -56
  318. package/dist/node_modules/minipass-flush/package.json +0 -42
  319. package/dist/node_modules/minipass-pipeline/LICENSE +0 -15
  320. package/dist/node_modules/minipass-pipeline/index.js +0 -128
  321. package/dist/node_modules/minipass-pipeline/node_modules/minipass/LICENSE +0 -15
  322. package/dist/node_modules/minipass-pipeline/node_modules/minipass/index.js +0 -649
  323. package/dist/node_modules/minipass-pipeline/node_modules/minipass/package.json +0 -56
  324. package/dist/node_modules/minipass-pipeline/package.json +0 -29
  325. package/dist/node_modules/minipass-sized/LICENSE +0 -15
  326. package/dist/node_modules/minipass-sized/dist/commonjs/index.js +0 -69
  327. package/dist/node_modules/minipass-sized/dist/commonjs/package.json +0 -3
  328. package/dist/node_modules/minipass-sized/dist/esm/index.js +0 -64
  329. package/dist/node_modules/minipass-sized/dist/esm/package.json +0 -3
  330. package/dist/node_modules/minipass-sized/package.json +0 -69
  331. package/dist/node_modules/ms/index.js +0 -162
  332. package/dist/node_modules/ms/package.json +0 -38
  333. package/dist/node_modules/negotiator/LICENSE +0 -24
  334. package/dist/node_modules/negotiator/index.js +0 -83
  335. package/dist/node_modules/negotiator/lib/charset.js +0 -169
  336. package/dist/node_modules/negotiator/lib/encoding.js +0 -205
  337. package/dist/node_modules/negotiator/lib/language.js +0 -179
  338. package/dist/node_modules/negotiator/lib/mediaType.js +0 -294
  339. package/dist/node_modules/negotiator/package.json +0 -43
  340. package/dist/node_modules/p-map/index.js +0 -283
  341. package/dist/node_modules/p-map/license +0 -9
  342. package/dist/node_modules/p-map/package.json +0 -57
  343. package/dist/node_modules/path-scurry/dist/commonjs/index.js +0 -2018
  344. package/dist/node_modules/path-scurry/dist/commonjs/package.json +0 -3
  345. package/dist/node_modules/path-scurry/dist/esm/index.js +0 -1983
  346. package/dist/node_modules/path-scurry/dist/esm/package.json +0 -3
  347. package/dist/node_modules/path-scurry/package.json +0 -72
  348. package/dist/node_modules/safer-buffer/dangerous.js +0 -58
  349. package/dist/node_modules/safer-buffer/package.json +0 -34
  350. package/dist/node_modules/safer-buffer/safer.js +0 -77
  351. package/dist/node_modules/safer-buffer/tests.js +0 -406
  352. package/dist/node_modules/smart-buffer/.prettierrc.yaml +0 -5
  353. package/dist/node_modules/smart-buffer/LICENSE +0 -20
  354. package/dist/node_modules/smart-buffer/build/smartbuffer.js +0 -1233
  355. package/dist/node_modules/smart-buffer/build/utils.js +0 -108
  356. package/dist/node_modules/smart-buffer/package.json +0 -79
  357. package/dist/node_modules/socks/.eslintrc.cjs +0 -11
  358. package/dist/node_modules/socks/.prettierrc.yaml +0 -7
  359. package/dist/node_modules/socks/LICENSE +0 -20
  360. package/dist/node_modules/socks/build/client/socksclient.js +0 -793
  361. package/dist/node_modules/socks/build/common/constants.js +0 -108
  362. package/dist/node_modules/socks/build/common/helpers.js +0 -167
  363. package/dist/node_modules/socks/build/common/receivebuffer.js +0 -43
  364. package/dist/node_modules/socks/build/common/util.js +0 -25
  365. package/dist/node_modules/socks/build/index.js +0 -18
  366. package/dist/node_modules/socks/package.json +0 -58
  367. package/dist/node_modules/socks-proxy-agent/LICENSE +0 -22
  368. package/dist/node_modules/socks-proxy-agent/dist/index.js +0 -195
  369. package/dist/node_modules/socks-proxy-agent/package.json +0 -142
  370. package/dist/node_modules/ssri/lib/index.js +0 -550
  371. package/dist/node_modules/ssri/package.json +0 -66
  372. package/dist/node_modules/tar/node_modules/yallist/dist/commonjs/package.json +0 -3
  373. package/dist/node_modules/tar/node_modules/yallist/dist/esm/package.json +0 -3
  374. package/dist/node_modules/tar/node_modules/yallist/package.json +0 -68
  375. package/dist/node_modules/yallist/LICENSE +0 -15
  376. package/dist/node_modules/yallist/iterator.js +0 -8
  377. package/dist/node_modules/yallist/yallist.js +0 -426
  378. /package/dist/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/index.js +0 -0
  379. /package/dist/node_modules/{balanced-match → yallist}/dist/commonjs/package.json +0 -0
  380. /package/dist/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/index.js +0 -0
  381. /package/dist/node_modules/{balanced-match → yallist}/dist/esm/package.json +0 -0
@@ -0,0 +1,2272 @@
1
+ // https://github.com/Ethan-Arrowood/undici-fetch
2
+
3
+ 'use strict'
4
+
5
+ const {
6
+ makeNetworkError,
7
+ makeAppropriateNetworkError,
8
+ filterResponse,
9
+ makeResponse,
10
+ fromInnerResponse
11
+ } = require('./response')
12
+ const { HeadersList } = require('./headers')
13
+ const { Request, cloneRequest } = require('./request')
14
+ const zlib = require('node:zlib')
15
+ const {
16
+ bytesMatch,
17
+ makePolicyContainer,
18
+ clonePolicyContainer,
19
+ requestBadPort,
20
+ TAOCheck,
21
+ appendRequestOriginHeader,
22
+ responseLocationURL,
23
+ requestCurrentURL,
24
+ setRequestReferrerPolicyOnRedirect,
25
+ tryUpgradeRequestToAPotentiallyTrustworthyURL,
26
+ createOpaqueTimingInfo,
27
+ appendFetchMetadata,
28
+ corsCheck,
29
+ crossOriginResourcePolicyCheck,
30
+ determineRequestsReferrer,
31
+ coarsenedSharedCurrentTime,
32
+ createDeferredPromise,
33
+ isBlobLike,
34
+ sameOrigin,
35
+ isCancelled,
36
+ isAborted,
37
+ isErrorLike,
38
+ fullyReadBody,
39
+ readableStreamClose,
40
+ isomorphicEncode,
41
+ urlIsLocal,
42
+ urlIsHttpHttpsScheme,
43
+ urlHasHttpsScheme,
44
+ clampAndCoarsenConnectionTimingInfo,
45
+ simpleRangeHeaderValue,
46
+ buildContentRange,
47
+ createInflate,
48
+ extractMimeType
49
+ } = require('./util')
50
+ const { kState, kDispatcher } = require('./symbols')
51
+ const assert = require('node:assert')
52
+ const { safelyExtractBody, extractBody } = require('./body')
53
+ const {
54
+ redirectStatusSet,
55
+ nullBodyStatus,
56
+ safeMethodsSet,
57
+ requestBodyHeader,
58
+ subresourceSet
59
+ } = require('./constants')
60
+ const EE = require('node:events')
61
+ const { Readable, pipeline, finished } = require('node:stream')
62
+ const { addAbortListener, isErrored, isReadable, bufferToLowerCasedHeaderName } = require('../../core/util')
63
+ const { dataURLProcessor, serializeAMimeType, minimizeSupportedMimeType } = require('./data-url')
64
+ const { getGlobalDispatcher } = require('../../global')
65
+ const { webidl } = require('./webidl')
66
+ const { STATUS_CODES } = require('node:http')
67
+ const GET_OR_HEAD = ['GET', 'HEAD']
68
+
69
+ const defaultUserAgent = typeof __UNDICI_IS_NODE__ !== 'undefined' || typeof esbuildDetection !== 'undefined'
70
+ ? 'node'
71
+ : 'undici'
72
+
73
+ /** @type {import('buffer').resolveObjectURL} */
74
+ let resolveObjectURL
75
+
76
+ class Fetch extends EE {
77
+ constructor (dispatcher) {
78
+ super()
79
+
80
+ this.dispatcher = dispatcher
81
+ this.connection = null
82
+ this.dump = false
83
+ this.state = 'ongoing'
84
+ }
85
+
86
+ terminate (reason) {
87
+ if (this.state !== 'ongoing') {
88
+ return
89
+ }
90
+
91
+ this.state = 'terminated'
92
+ this.connection?.destroy(reason)
93
+ this.emit('terminated', reason)
94
+ }
95
+
96
+ // https://fetch.spec.whatwg.org/#fetch-controller-abort
97
+ abort (error) {
98
+ if (this.state !== 'ongoing') {
99
+ return
100
+ }
101
+
102
+ // 1. Set controller’s state to "aborted".
103
+ this.state = 'aborted'
104
+
105
+ // 2. Let fallbackError be an "AbortError" DOMException.
106
+ // 3. Set error to fallbackError if it is not given.
107
+ if (!error) {
108
+ error = new DOMException('The operation was aborted.', 'AbortError')
109
+ }
110
+
111
+ // 4. Let serializedError be StructuredSerialize(error).
112
+ // If that threw an exception, catch it, and let
113
+ // serializedError be StructuredSerialize(fallbackError).
114
+
115
+ // 5. Set controller’s serialized abort reason to serializedError.
116
+ this.serializedAbortReason = error
117
+
118
+ this.connection?.destroy(error)
119
+ this.emit('terminated', error)
120
+ }
121
+ }
122
+
123
+ function handleFetchDone (response) {
124
+ finalizeAndReportTiming(response, 'fetch')
125
+ }
126
+
127
+ // https://fetch.spec.whatwg.org/#fetch-method
128
+ function fetch (input, init = undefined) {
129
+ webidl.argumentLengthCheck(arguments, 1, 'globalThis.fetch')
130
+
131
+ // 1. Let p be a new promise.
132
+ let p = createDeferredPromise()
133
+
134
+ // 2. Let requestObject be the result of invoking the initial value of
135
+ // Request as constructor with input and init as arguments. If this throws
136
+ // an exception, reject p with it and return p.
137
+ let requestObject
138
+
139
+ try {
140
+ requestObject = new Request(input, init)
141
+ } catch (e) {
142
+ p.reject(e)
143
+ return p.promise
144
+ }
145
+
146
+ // 3. Let request be requestObject’s request.
147
+ const request = requestObject[kState]
148
+
149
+ // 4. If requestObject’s signal’s aborted flag is set, then:
150
+ if (requestObject.signal.aborted) {
151
+ // 1. Abort the fetch() call with p, request, null, and
152
+ // requestObject’s signal’s abort reason.
153
+ abortFetch(p, request, null, requestObject.signal.reason)
154
+
155
+ // 2. Return p.
156
+ return p.promise
157
+ }
158
+
159
+ // 5. Let globalObject be request’s client’s global object.
160
+ const globalObject = request.client.globalObject
161
+
162
+ // 6. If globalObject is a ServiceWorkerGlobalScope object, then set
163
+ // request’s service-workers mode to "none".
164
+ if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') {
165
+ request.serviceWorkers = 'none'
166
+ }
167
+
168
+ // 7. Let responseObject be null.
169
+ let responseObject = null
170
+
171
+ // 8. Let relevantRealm be this’s relevant Realm.
172
+
173
+ // 9. Let locallyAborted be false.
174
+ let locallyAborted = false
175
+
176
+ // 10. Let controller be null.
177
+ let controller = null
178
+
179
+ // 11. Add the following abort steps to requestObject’s signal:
180
+ addAbortListener(
181
+ requestObject.signal,
182
+ () => {
183
+ // 1. Set locallyAborted to true.
184
+ locallyAborted = true
185
+
186
+ // 2. Assert: controller is non-null.
187
+ assert(controller != null)
188
+
189
+ // 3. Abort controller with requestObject’s signal’s abort reason.
190
+ controller.abort(requestObject.signal.reason)
191
+
192
+ const realResponse = responseObject?.deref()
193
+
194
+ // 4. Abort the fetch() call with p, request, responseObject,
195
+ // and requestObject’s signal’s abort reason.
196
+ abortFetch(p, request, realResponse, requestObject.signal.reason)
197
+ }
198
+ )
199
+
200
+ // 12. Let handleFetchDone given response response be to finalize and
201
+ // report timing with response, globalObject, and "fetch".
202
+ // see function handleFetchDone
203
+
204
+ // 13. Set controller to the result of calling fetch given request,
205
+ // with processResponseEndOfBody set to handleFetchDone, and processResponse
206
+ // given response being these substeps:
207
+
208
+ const processResponse = (response) => {
209
+ // 1. If locallyAborted is true, terminate these substeps.
210
+ if (locallyAborted) {
211
+ return
212
+ }
213
+
214
+ // 2. If response’s aborted flag is set, then:
215
+ if (response.aborted) {
216
+ // 1. Let deserializedError be the result of deserialize a serialized
217
+ // abort reason given controller’s serialized abort reason and
218
+ // relevantRealm.
219
+
220
+ // 2. Abort the fetch() call with p, request, responseObject, and
221
+ // deserializedError.
222
+
223
+ abortFetch(p, request, responseObject, controller.serializedAbortReason)
224
+ return
225
+ }
226
+
227
+ // 3. If response is a network error, then reject p with a TypeError
228
+ // and terminate these substeps.
229
+ if (response.type === 'error') {
230
+ p.reject(new TypeError('fetch failed', { cause: response.error }))
231
+ return
232
+ }
233
+
234
+ // 4. Set responseObject to the result of creating a Response object,
235
+ // given response, "immutable", and relevantRealm.
236
+ responseObject = new WeakRef(fromInnerResponse(response, 'immutable'))
237
+
238
+ // 5. Resolve p with responseObject.
239
+ p.resolve(responseObject.deref())
240
+ p = null
241
+ }
242
+
243
+ controller = fetching({
244
+ request,
245
+ processResponseEndOfBody: handleFetchDone,
246
+ processResponse,
247
+ dispatcher: requestObject[kDispatcher] // undici
248
+ })
249
+
250
+ // 14. Return p.
251
+ return p.promise
252
+ }
253
+
254
+ // https://fetch.spec.whatwg.org/#finalize-and-report-timing
255
+ function finalizeAndReportTiming (response, initiatorType = 'other') {
256
+ // 1. If response is an aborted network error, then return.
257
+ if (response.type === 'error' && response.aborted) {
258
+ return
259
+ }
260
+
261
+ // 2. If response’s URL list is null or empty, then return.
262
+ if (!response.urlList?.length) {
263
+ return
264
+ }
265
+
266
+ // 3. Let originalURL be response’s URL list[0].
267
+ const originalURL = response.urlList[0]
268
+
269
+ // 4. Let timingInfo be response’s timing info.
270
+ let timingInfo = response.timingInfo
271
+
272
+ // 5. Let cacheState be response’s cache state.
273
+ let cacheState = response.cacheState
274
+
275
+ // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return.
276
+ if (!urlIsHttpHttpsScheme(originalURL)) {
277
+ return
278
+ }
279
+
280
+ // 7. If timingInfo is null, then return.
281
+ if (timingInfo === null) {
282
+ return
283
+ }
284
+
285
+ // 8. If response’s timing allow passed flag is not set, then:
286
+ if (!response.timingAllowPassed) {
287
+ // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo.
288
+ timingInfo = createOpaqueTimingInfo({
289
+ startTime: timingInfo.startTime
290
+ })
291
+
292
+ // 2. Set cacheState to the empty string.
293
+ cacheState = ''
294
+ }
295
+
296
+ // 9. Set timingInfo’s end time to the coarsened shared current time
297
+ // given global’s relevant settings object’s cross-origin isolated
298
+ // capability.
299
+ // TODO: given global’s relevant settings object’s cross-origin isolated
300
+ // capability?
301
+ timingInfo.endTime = coarsenedSharedCurrentTime()
302
+
303
+ // 10. Set response’s timing info to timingInfo.
304
+ response.timingInfo = timingInfo
305
+
306
+ // 11. Mark resource timing for timingInfo, originalURL, initiatorType,
307
+ // global, and cacheState.
308
+ markResourceTiming(
309
+ timingInfo,
310
+ originalURL.href,
311
+ initiatorType,
312
+ globalThis,
313
+ cacheState
314
+ )
315
+ }
316
+
317
+ // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing
318
+ const markResourceTiming = performance.markResourceTiming
319
+
320
+ // https://fetch.spec.whatwg.org/#abort-fetch
321
+ function abortFetch (p, request, responseObject, error) {
322
+ // 1. Reject promise with error.
323
+ if (p) {
324
+ // We might have already resolved the promise at this stage
325
+ p.reject(error)
326
+ }
327
+
328
+ // 2. If request’s body is not null and is readable, then cancel request’s
329
+ // body with error.
330
+ if (request.body != null && isReadable(request.body?.stream)) {
331
+ request.body.stream.cancel(error).catch((err) => {
332
+ if (err.code === 'ERR_INVALID_STATE') {
333
+ // Node bug?
334
+ return
335
+ }
336
+ throw err
337
+ })
338
+ }
339
+
340
+ // 3. If responseObject is null, then return.
341
+ if (responseObject == null) {
342
+ return
343
+ }
344
+
345
+ // 4. Let response be responseObject’s response.
346
+ const response = responseObject[kState]
347
+
348
+ // 5. If response’s body is not null and is readable, then error response’s
349
+ // body with error.
350
+ if (response.body != null && isReadable(response.body?.stream)) {
351
+ response.body.stream.cancel(error).catch((err) => {
352
+ if (err.code === 'ERR_INVALID_STATE') {
353
+ // Node bug?
354
+ return
355
+ }
356
+ throw err
357
+ })
358
+ }
359
+ }
360
+
361
+ // https://fetch.spec.whatwg.org/#fetching
362
+ function fetching ({
363
+ request,
364
+ processRequestBodyChunkLength,
365
+ processRequestEndOfBody,
366
+ processResponse,
367
+ processResponseEndOfBody,
368
+ processResponseConsumeBody,
369
+ useParallelQueue = false,
370
+ dispatcher = getGlobalDispatcher() // undici
371
+ }) {
372
+ // Ensure that the dispatcher is set accordingly
373
+ assert(dispatcher)
374
+
375
+ // 1. Let taskDestination be null.
376
+ let taskDestination = null
377
+
378
+ // 2. Let crossOriginIsolatedCapability be false.
379
+ let crossOriginIsolatedCapability = false
380
+
381
+ // 3. If request’s client is non-null, then:
382
+ if (request.client != null) {
383
+ // 1. Set taskDestination to request’s client’s global object.
384
+ taskDestination = request.client.globalObject
385
+
386
+ // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin
387
+ // isolated capability.
388
+ crossOriginIsolatedCapability =
389
+ request.client.crossOriginIsolatedCapability
390
+ }
391
+
392
+ // 4. If useParallelQueue is true, then set taskDestination to the result of
393
+ // starting a new parallel queue.
394
+ // TODO
395
+
396
+ // 5. Let timingInfo be a new fetch timing info whose start time and
397
+ // post-redirect start time are the coarsened shared current time given
398
+ // crossOriginIsolatedCapability.
399
+ const currentTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability)
400
+ const timingInfo = createOpaqueTimingInfo({
401
+ startTime: currentTime
402
+ })
403
+
404
+ // 6. Let fetchParams be a new fetch params whose
405
+ // request is request,
406
+ // timing info is timingInfo,
407
+ // process request body chunk length is processRequestBodyChunkLength,
408
+ // process request end-of-body is processRequestEndOfBody,
409
+ // process response is processResponse,
410
+ // process response consume body is processResponseConsumeBody,
411
+ // process response end-of-body is processResponseEndOfBody,
412
+ // task destination is taskDestination,
413
+ // and cross-origin isolated capability is crossOriginIsolatedCapability.
414
+ const fetchParams = {
415
+ controller: new Fetch(dispatcher),
416
+ request,
417
+ timingInfo,
418
+ processRequestBodyChunkLength,
419
+ processRequestEndOfBody,
420
+ processResponse,
421
+ processResponseConsumeBody,
422
+ processResponseEndOfBody,
423
+ taskDestination,
424
+ crossOriginIsolatedCapability
425
+ }
426
+
427
+ // 7. If request’s body is a byte sequence, then set request’s body to
428
+ // request’s body as a body.
429
+ // NOTE: Since fetching is only called from fetch, body should already be
430
+ // extracted.
431
+ assert(!request.body || request.body.stream)
432
+
433
+ // 8. If request’s window is "client", then set request’s window to request’s
434
+ // client, if request’s client’s global object is a Window object; otherwise
435
+ // "no-window".
436
+ if (request.window === 'client') {
437
+ // TODO: What if request.client is null?
438
+ request.window =
439
+ request.client?.globalObject?.constructor?.name === 'Window'
440
+ ? request.client
441
+ : 'no-window'
442
+ }
443
+
444
+ // 9. If request’s origin is "client", then set request’s origin to request’s
445
+ // client’s origin.
446
+ if (request.origin === 'client') {
447
+ request.origin = request.client.origin
448
+ }
449
+
450
+ // 10. If all of the following conditions are true:
451
+ // TODO
452
+
453
+ // 11. If request’s policy container is "client", then:
454
+ if (request.policyContainer === 'client') {
455
+ // 1. If request’s client is non-null, then set request’s policy
456
+ // container to a clone of request’s client’s policy container. [HTML]
457
+ if (request.client != null) {
458
+ request.policyContainer = clonePolicyContainer(
459
+ request.client.policyContainer
460
+ )
461
+ } else {
462
+ // 2. Otherwise, set request’s policy container to a new policy
463
+ // container.
464
+ request.policyContainer = makePolicyContainer()
465
+ }
466
+ }
467
+
468
+ // 12. If request’s header list does not contain `Accept`, then:
469
+ if (!request.headersList.contains('accept', true)) {
470
+ // 1. Let value be `*/*`.
471
+ const value = '*/*'
472
+
473
+ // 2. A user agent should set value to the first matching statement, if
474
+ // any, switching on request’s destination:
475
+ // "document"
476
+ // "frame"
477
+ // "iframe"
478
+ // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`
479
+ // "image"
480
+ // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5`
481
+ // "style"
482
+ // `text/css,*/*;q=0.1`
483
+ // TODO
484
+
485
+ // 3. Append `Accept`/value to request’s header list.
486
+ request.headersList.append('accept', value, true)
487
+ }
488
+
489
+ // 13. If request’s header list does not contain `Accept-Language`, then
490
+ // user agents should append `Accept-Language`/an appropriate value to
491
+ // request’s header list.
492
+ if (!request.headersList.contains('accept-language', true)) {
493
+ request.headersList.append('accept-language', '*', true)
494
+ }
495
+
496
+ // 14. If request’s priority is null, then use request’s initiator and
497
+ // destination appropriately in setting request’s priority to a
498
+ // user-agent-defined object.
499
+ if (request.priority === null) {
500
+ // TODO
501
+ }
502
+
503
+ // 15. If request is a subresource request, then:
504
+ if (subresourceSet.has(request.destination)) {
505
+ // TODO
506
+ }
507
+
508
+ // 16. Run main fetch given fetchParams.
509
+ mainFetch(fetchParams)
510
+ .catch(err => {
511
+ fetchParams.controller.terminate(err)
512
+ })
513
+
514
+ // 17. Return fetchParam's controller
515
+ return fetchParams.controller
516
+ }
517
+
518
+ // https://fetch.spec.whatwg.org/#concept-main-fetch
519
+ async function mainFetch (fetchParams, recursive = false) {
520
+ // 1. Let request be fetchParams’s request.
521
+ const request = fetchParams.request
522
+
523
+ // 2. Let response be null.
524
+ let response = null
525
+
526
+ // 3. If request’s local-URLs-only flag is set and request’s current URL is
527
+ // not local, then set response to a network error.
528
+ if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) {
529
+ response = makeNetworkError('local URLs only')
530
+ }
531
+
532
+ // 4. Run report Content Security Policy violations for request.
533
+ // TODO
534
+
535
+ // 5. Upgrade request to a potentially trustworthy URL, if appropriate.
536
+ tryUpgradeRequestToAPotentiallyTrustworthyURL(request)
537
+
538
+ // 6. If should request be blocked due to a bad port, should fetching request
539
+ // be blocked as mixed content, or should request be blocked by Content
540
+ // Security Policy returns blocked, then set response to a network error.
541
+ if (requestBadPort(request) === 'blocked') {
542
+ response = makeNetworkError('bad port')
543
+ }
544
+ // TODO: should fetching request be blocked as mixed content?
545
+ // TODO: should request be blocked by Content Security Policy?
546
+
547
+ // 7. If request’s referrer policy is the empty string, then set request’s
548
+ // referrer policy to request’s policy container’s referrer policy.
549
+ if (request.referrerPolicy === '') {
550
+ request.referrerPolicy = request.policyContainer.referrerPolicy
551
+ }
552
+
553
+ // 8. If request’s referrer is not "no-referrer", then set request’s
554
+ // referrer to the result of invoking determine request’s referrer.
555
+ if (request.referrer !== 'no-referrer') {
556
+ request.referrer = determineRequestsReferrer(request)
557
+ }
558
+
559
+ // 9. Set request’s current URL’s scheme to "https" if all of the following
560
+ // conditions are true:
561
+ // - request’s current URL’s scheme is "http"
562
+ // - request’s current URL’s host is a domain
563
+ // - Matching request’s current URL’s host per Known HSTS Host Domain Name
564
+ // Matching results in either a superdomain match with an asserted
565
+ // includeSubDomains directive or a congruent match (with or without an
566
+ // asserted includeSubDomains directive). [HSTS]
567
+ // TODO
568
+
569
+ // 10. If recursive is false, then run the remaining steps in parallel.
570
+ // TODO
571
+
572
+ // 11. If response is null, then set response to the result of running
573
+ // the steps corresponding to the first matching statement:
574
+ if (response === null) {
575
+ response = await (async () => {
576
+ const currentURL = requestCurrentURL(request)
577
+
578
+ if (
579
+ // - request’s current URL’s origin is same origin with request’s origin,
580
+ // and request’s response tainting is "basic"
581
+ (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') ||
582
+ // request’s current URL’s scheme is "data"
583
+ (currentURL.protocol === 'data:') ||
584
+ // - request’s mode is "navigate" or "websocket"
585
+ (request.mode === 'navigate' || request.mode === 'websocket')
586
+ ) {
587
+ // 1. Set request’s response tainting to "basic".
588
+ request.responseTainting = 'basic'
589
+
590
+ // 2. Return the result of running scheme fetch given fetchParams.
591
+ return await schemeFetch(fetchParams)
592
+ }
593
+
594
+ // request’s mode is "same-origin"
595
+ if (request.mode === 'same-origin') {
596
+ // 1. Return a network error.
597
+ return makeNetworkError('request mode cannot be "same-origin"')
598
+ }
599
+
600
+ // request’s mode is "no-cors"
601
+ if (request.mode === 'no-cors') {
602
+ // 1. If request’s redirect mode is not "follow", then return a network
603
+ // error.
604
+ if (request.redirect !== 'follow') {
605
+ return makeNetworkError(
606
+ 'redirect mode cannot be "follow" for "no-cors" request'
607
+ )
608
+ }
609
+
610
+ // 2. Set request’s response tainting to "opaque".
611
+ request.responseTainting = 'opaque'
612
+
613
+ // 3. Return the result of running scheme fetch given fetchParams.
614
+ return await schemeFetch(fetchParams)
615
+ }
616
+
617
+ // request’s current URL’s scheme is not an HTTP(S) scheme
618
+ if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) {
619
+ // Return a network error.
620
+ return makeNetworkError('URL scheme must be a HTTP(S) scheme')
621
+ }
622
+
623
+ // - request’s use-CORS-preflight flag is set
624
+ // - request’s unsafe-request flag is set and either request’s method is
625
+ // not a CORS-safelisted method or CORS-unsafe request-header names with
626
+ // request’s header list is not empty
627
+ // 1. Set request’s response tainting to "cors".
628
+ // 2. Let corsWithPreflightResponse be the result of running HTTP fetch
629
+ // given fetchParams and true.
630
+ // 3. If corsWithPreflightResponse is a network error, then clear cache
631
+ // entries using request.
632
+ // 4. Return corsWithPreflightResponse.
633
+ // TODO
634
+
635
+ // Otherwise
636
+ // 1. Set request’s response tainting to "cors".
637
+ request.responseTainting = 'cors'
638
+
639
+ // 2. Return the result of running HTTP fetch given fetchParams.
640
+ return await httpFetch(fetchParams)
641
+ })()
642
+ }
643
+
644
+ // 12. If recursive is true, then return response.
645
+ if (recursive) {
646
+ return response
647
+ }
648
+
649
+ // 13. If response is not a network error and response is not a filtered
650
+ // response, then:
651
+ if (response.status !== 0 && !response.internalResponse) {
652
+ // If request’s response tainting is "cors", then:
653
+ if (request.responseTainting === 'cors') {
654
+ // 1. Let headerNames be the result of extracting header list values
655
+ // given `Access-Control-Expose-Headers` and response’s header list.
656
+ // TODO
657
+ // 2. If request’s credentials mode is not "include" and headerNames
658
+ // contains `*`, then set response’s CORS-exposed header-name list to
659
+ // all unique header names in response’s header list.
660
+ // TODO
661
+ // 3. Otherwise, if headerNames is not null or failure, then set
662
+ // response’s CORS-exposed header-name list to headerNames.
663
+ // TODO
664
+ }
665
+
666
+ // Set response to the following filtered response with response as its
667
+ // internal response, depending on request’s response tainting:
668
+ if (request.responseTainting === 'basic') {
669
+ response = filterResponse(response, 'basic')
670
+ } else if (request.responseTainting === 'cors') {
671
+ response = filterResponse(response, 'cors')
672
+ } else if (request.responseTainting === 'opaque') {
673
+ response = filterResponse(response, 'opaque')
674
+ } else {
675
+ assert(false)
676
+ }
677
+ }
678
+
679
+ // 14. Let internalResponse be response, if response is a network error,
680
+ // and response’s internal response otherwise.
681
+ let internalResponse =
682
+ response.status === 0 ? response : response.internalResponse
683
+
684
+ // 15. If internalResponse’s URL list is empty, then set it to a clone of
685
+ // request’s URL list.
686
+ if (internalResponse.urlList.length === 0) {
687
+ internalResponse.urlList.push(...request.urlList)
688
+ }
689
+
690
+ // 16. If request’s timing allow failed flag is unset, then set
691
+ // internalResponse’s timing allow passed flag.
692
+ if (!request.timingAllowFailed) {
693
+ response.timingAllowPassed = true
694
+ }
695
+
696
+ // 17. If response is not a network error and any of the following returns
697
+ // blocked
698
+ // - should internalResponse to request be blocked as mixed content
699
+ // - should internalResponse to request be blocked by Content Security Policy
700
+ // - should internalResponse to request be blocked due to its MIME type
701
+ // - should internalResponse to request be blocked due to nosniff
702
+ // TODO
703
+
704
+ // 18. If response’s type is "opaque", internalResponse’s status is 206,
705
+ // internalResponse’s range-requested flag is set, and request’s header
706
+ // list does not contain `Range`, then set response and internalResponse
707
+ // to a network error.
708
+ if (
709
+ response.type === 'opaque' &&
710
+ internalResponse.status === 206 &&
711
+ internalResponse.rangeRequested &&
712
+ !request.headers.contains('range', true)
713
+ ) {
714
+ response = internalResponse = makeNetworkError()
715
+ }
716
+
717
+ // 19. If response is not a network error and either request’s method is
718
+ // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status,
719
+ // set internalResponse’s body to null and disregard any enqueuing toward
720
+ // it (if any).
721
+ if (
722
+ response.status !== 0 &&
723
+ (request.method === 'HEAD' ||
724
+ request.method === 'CONNECT' ||
725
+ nullBodyStatus.includes(internalResponse.status))
726
+ ) {
727
+ internalResponse.body = null
728
+ fetchParams.controller.dump = true
729
+ }
730
+
731
+ // 20. If request’s integrity metadata is not the empty string, then:
732
+ if (request.integrity) {
733
+ // 1. Let processBodyError be this step: run fetch finale given fetchParams
734
+ // and a network error.
735
+ const processBodyError = (reason) =>
736
+ fetchFinale(fetchParams, makeNetworkError(reason))
737
+
738
+ // 2. If request’s response tainting is "opaque", or response’s body is null,
739
+ // then run processBodyError and abort these steps.
740
+ if (request.responseTainting === 'opaque' || response.body == null) {
741
+ processBodyError(response.error)
742
+ return
743
+ }
744
+
745
+ // 3. Let processBody given bytes be these steps:
746
+ const processBody = (bytes) => {
747
+ // 1. If bytes do not match request’s integrity metadata,
748
+ // then run processBodyError and abort these steps. [SRI]
749
+ if (!bytesMatch(bytes, request.integrity)) {
750
+ processBodyError('integrity mismatch')
751
+ return
752
+ }
753
+
754
+ // 2. Set response’s body to bytes as a body.
755
+ response.body = safelyExtractBody(bytes)[0]
756
+
757
+ // 3. Run fetch finale given fetchParams and response.
758
+ fetchFinale(fetchParams, response)
759
+ }
760
+
761
+ // 4. Fully read response’s body given processBody and processBodyError.
762
+ await fullyReadBody(response.body, processBody, processBodyError)
763
+ } else {
764
+ // 21. Otherwise, run fetch finale given fetchParams and response.
765
+ fetchFinale(fetchParams, response)
766
+ }
767
+ }
768
+
769
+ // https://fetch.spec.whatwg.org/#concept-scheme-fetch
770
+ // given a fetch params fetchParams
771
+ function schemeFetch (fetchParams) {
772
+ // Note: since the connection is destroyed on redirect, which sets fetchParams to a
773
+ // cancelled state, we do not want this condition to trigger *unless* there have been
774
+ // no redirects. See https://github.com/nodejs/undici/issues/1776
775
+ // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams.
776
+ if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) {
777
+ return Promise.resolve(makeAppropriateNetworkError(fetchParams))
778
+ }
779
+
780
+ // 2. Let request be fetchParams’s request.
781
+ const { request } = fetchParams
782
+
783
+ const { protocol: scheme } = requestCurrentURL(request)
784
+
785
+ // 3. Switch on request’s current URL’s scheme and run the associated steps:
786
+ switch (scheme) {
787
+ case 'about:': {
788
+ // If request’s current URL’s path is the string "blank", then return a new response
789
+ // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) »,
790
+ // and body is the empty byte sequence as a body.
791
+
792
+ // Otherwise, return a network error.
793
+ return Promise.resolve(makeNetworkError('about scheme is not supported'))
794
+ }
795
+ case 'blob:': {
796
+ if (!resolveObjectURL) {
797
+ resolveObjectURL = require('node:buffer').resolveObjectURL
798
+ }
799
+
800
+ // 1. Let blobURLEntry be request’s current URL’s blob URL entry.
801
+ const blobURLEntry = requestCurrentURL(request)
802
+
803
+ // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56
804
+ // Buffer.resolveObjectURL does not ignore URL queries.
805
+ if (blobURLEntry.search.length !== 0) {
806
+ return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.'))
807
+ }
808
+
809
+ const blob = resolveObjectURL(blobURLEntry.toString())
810
+
811
+ // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s
812
+ // object is not a Blob object, then return a network error.
813
+ if (request.method !== 'GET' || !isBlobLike(blob)) {
814
+ return Promise.resolve(makeNetworkError('invalid method'))
815
+ }
816
+
817
+ // 3. Let blob be blobURLEntry’s object.
818
+ // Note: done above
819
+
820
+ // 4. Let response be a new response.
821
+ const response = makeResponse()
822
+
823
+ // 5. Let fullLength be blob’s size.
824
+ const fullLength = blob.size
825
+
826
+ // 6. Let serializedFullLength be fullLength, serialized and isomorphic encoded.
827
+ const serializedFullLength = isomorphicEncode(`${fullLength}`)
828
+
829
+ // 7. Let type be blob’s type.
830
+ const type = blob.type
831
+
832
+ // 8. If request’s header list does not contain `Range`:
833
+ // 9. Otherwise:
834
+ if (!request.headersList.contains('range', true)) {
835
+ // 1. Let bodyWithType be the result of safely extracting blob.
836
+ // Note: in the FileAPI a blob "object" is a Blob *or* a MediaSource.
837
+ // In node, this can only ever be a Blob. Therefore we can safely
838
+ // use extractBody directly.
839
+ const bodyWithType = extractBody(blob)
840
+
841
+ // 2. Set response’s status message to `OK`.
842
+ response.statusText = 'OK'
843
+
844
+ // 3. Set response’s body to bodyWithType’s body.
845
+ response.body = bodyWithType[0]
846
+
847
+ // 4. Set response’s header list to « (`Content-Length`, serializedFullLength), (`Content-Type`, type) ».
848
+ response.headersList.set('content-length', serializedFullLength, true)
849
+ response.headersList.set('content-type', type, true)
850
+ } else {
851
+ // 1. Set response’s range-requested flag.
852
+ response.rangeRequested = true
853
+
854
+ // 2. Let rangeHeader be the result of getting `Range` from request’s header list.
855
+ const rangeHeader = request.headersList.get('range', true)
856
+
857
+ // 3. Let rangeValue be the result of parsing a single range header value given rangeHeader and true.
858
+ const rangeValue = simpleRangeHeaderValue(rangeHeader, true)
859
+
860
+ // 4. If rangeValue is failure, then return a network error.
861
+ if (rangeValue === 'failure') {
862
+ return Promise.resolve(makeNetworkError('failed to fetch the data URL'))
863
+ }
864
+
865
+ // 5. Let (rangeStart, rangeEnd) be rangeValue.
866
+ let { rangeStartValue: rangeStart, rangeEndValue: rangeEnd } = rangeValue
867
+
868
+ // 6. If rangeStart is null:
869
+ // 7. Otherwise:
870
+ if (rangeStart === null) {
871
+ // 1. Set rangeStart to fullLength − rangeEnd.
872
+ rangeStart = fullLength - rangeEnd
873
+
874
+ // 2. Set rangeEnd to rangeStart + rangeEnd − 1.
875
+ rangeEnd = rangeStart + rangeEnd - 1
876
+ } else {
877
+ // 1. If rangeStart is greater than or equal to fullLength, then return a network error.
878
+ if (rangeStart >= fullLength) {
879
+ return Promise.resolve(makeNetworkError('Range start is greater than the blob\'s size.'))
880
+ }
881
+
882
+ // 2. If rangeEnd is null or rangeEnd is greater than or equal to fullLength, then set
883
+ // rangeEnd to fullLength − 1.
884
+ if (rangeEnd === null || rangeEnd >= fullLength) {
885
+ rangeEnd = fullLength - 1
886
+ }
887
+ }
888
+
889
+ // 8. Let slicedBlob be the result of invoking slice blob given blob, rangeStart,
890
+ // rangeEnd + 1, and type.
891
+ const slicedBlob = blob.slice(rangeStart, rangeEnd, type)
892
+
893
+ // 9. Let slicedBodyWithType be the result of safely extracting slicedBlob.
894
+ // Note: same reason as mentioned above as to why we use extractBody
895
+ const slicedBodyWithType = extractBody(slicedBlob)
896
+
897
+ // 10. Set response’s body to slicedBodyWithType’s body.
898
+ response.body = slicedBodyWithType[0]
899
+
900
+ // 11. Let serializedSlicedLength be slicedBlob’s size, serialized and isomorphic encoded.
901
+ const serializedSlicedLength = isomorphicEncode(`${slicedBlob.size}`)
902
+
903
+ // 12. Let contentRange be the result of invoking build a content range given rangeStart,
904
+ // rangeEnd, and fullLength.
905
+ const contentRange = buildContentRange(rangeStart, rangeEnd, fullLength)
906
+
907
+ // 13. Set response’s status to 206.
908
+ response.status = 206
909
+
910
+ // 14. Set response’s status message to `Partial Content`.
911
+ response.statusText = 'Partial Content'
912
+
913
+ // 15. Set response’s header list to « (`Content-Length`, serializedSlicedLength),
914
+ // (`Content-Type`, type), (`Content-Range`, contentRange) ».
915
+ response.headersList.set('content-length', serializedSlicedLength, true)
916
+ response.headersList.set('content-type', type, true)
917
+ response.headersList.set('content-range', contentRange, true)
918
+ }
919
+
920
+ // 10. Return response.
921
+ return Promise.resolve(response)
922
+ }
923
+ case 'data:': {
924
+ // 1. Let dataURLStruct be the result of running the
925
+ // data: URL processor on request’s current URL.
926
+ const currentURL = requestCurrentURL(request)
927
+ const dataURLStruct = dataURLProcessor(currentURL)
928
+
929
+ // 2. If dataURLStruct is failure, then return a
930
+ // network error.
931
+ if (dataURLStruct === 'failure') {
932
+ return Promise.resolve(makeNetworkError('failed to fetch the data URL'))
933
+ }
934
+
935
+ // 3. Let mimeType be dataURLStruct’s MIME type, serialized.
936
+ const mimeType = serializeAMimeType(dataURLStruct.mimeType)
937
+
938
+ // 4. Return a response whose status message is `OK`,
939
+ // header list is « (`Content-Type`, mimeType) »,
940
+ // and body is dataURLStruct’s body as a body.
941
+ return Promise.resolve(makeResponse({
942
+ statusText: 'OK',
943
+ headersList: [
944
+ ['content-type', { name: 'Content-Type', value: mimeType }]
945
+ ],
946
+ body: safelyExtractBody(dataURLStruct.body)[0]
947
+ }))
948
+ }
949
+ case 'file:': {
950
+ // For now, unfortunate as it is, file URLs are left as an exercise for the reader.
951
+ // When in doubt, return a network error.
952
+ return Promise.resolve(makeNetworkError('not implemented... yet...'))
953
+ }
954
+ case 'http:':
955
+ case 'https:': {
956
+ // Return the result of running HTTP fetch given fetchParams.
957
+
958
+ return httpFetch(fetchParams)
959
+ .catch((err) => makeNetworkError(err))
960
+ }
961
+ default: {
962
+ return Promise.resolve(makeNetworkError('unknown scheme'))
963
+ }
964
+ }
965
+ }
966
+
967
+ // https://fetch.spec.whatwg.org/#finalize-response
968
+ function finalizeResponse (fetchParams, response) {
969
+ // 1. Set fetchParams’s request’s done flag.
970
+ fetchParams.request.done = true
971
+
972
+ // 2, If fetchParams’s process response done is not null, then queue a fetch
973
+ // task to run fetchParams’s process response done given response, with
974
+ // fetchParams’s task destination.
975
+ if (fetchParams.processResponseDone != null) {
976
+ queueMicrotask(() => fetchParams.processResponseDone(response))
977
+ }
978
+ }
979
+
980
+ // https://fetch.spec.whatwg.org/#fetch-finale
981
+ function fetchFinale (fetchParams, response) {
982
+ // 1. Let timingInfo be fetchParams’s timing info.
983
+ let timingInfo = fetchParams.timingInfo
984
+
985
+ // 2. If response is not a network error and fetchParams’s request’s client is a secure context,
986
+ // then set timingInfo’s server-timing headers to the result of getting, decoding, and splitting
987
+ // `Server-Timing` from response’s internal response’s header list.
988
+ // TODO
989
+
990
+ // 3. Let processResponseEndOfBody be the following steps:
991
+ const processResponseEndOfBody = () => {
992
+ // 1. Let unsafeEndTime be the unsafe shared current time.
993
+ const unsafeEndTime = Date.now() // ?
994
+
995
+ // 2. If fetchParams’s request’s destination is "document", then set fetchParams’s controller’s
996
+ // full timing info to fetchParams’s timing info.
997
+ if (fetchParams.request.destination === 'document') {
998
+ fetchParams.controller.fullTimingInfo = timingInfo
999
+ }
1000
+
1001
+ // 3. Set fetchParams’s controller’s report timing steps to the following steps given a global object global:
1002
+ fetchParams.controller.reportTimingSteps = () => {
1003
+ // 1. If fetchParams’s request’s URL’s scheme is not an HTTP(S) scheme, then return.
1004
+ if (fetchParams.request.url.protocol !== 'https:') {
1005
+ return
1006
+ }
1007
+
1008
+ // 2. Set timingInfo’s end time to the relative high resolution time given unsafeEndTime and global.
1009
+ timingInfo.endTime = unsafeEndTime
1010
+
1011
+ // 3. Let cacheState be response’s cache state.
1012
+ let cacheState = response.cacheState
1013
+
1014
+ // 4. Let bodyInfo be response’s body info.
1015
+ const bodyInfo = response.bodyInfo
1016
+
1017
+ // 5. If response’s timing allow passed flag is not set, then set timingInfo to the result of creating an
1018
+ // opaque timing info for timingInfo and set cacheState to the empty string.
1019
+ if (!response.timingAllowPassed) {
1020
+ timingInfo = createOpaqueTimingInfo(timingInfo)
1021
+
1022
+ cacheState = ''
1023
+ }
1024
+
1025
+ // 6. Let responseStatus be 0.
1026
+ let responseStatus = 0
1027
+
1028
+ // 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false:
1029
+ if (fetchParams.request.mode !== 'navigator' || !response.hasCrossOriginRedirects) {
1030
+ // 1. Set responseStatus to response’s status.
1031
+ responseStatus = response.status
1032
+
1033
+ // 2. Let mimeType be the result of extracting a MIME type from response’s header list.
1034
+ const mimeType = extractMimeType(response.headersList)
1035
+
1036
+ // 3. If mimeType is not failure, then set bodyInfo’s content type to the result of minimizing a supported MIME type given mimeType.
1037
+ if (mimeType !== 'failure') {
1038
+ bodyInfo.contentType = minimizeSupportedMimeType(mimeType)
1039
+ }
1040
+ }
1041
+
1042
+ // 8. If fetchParams’s request’s initiator type is non-null, then mark resource timing given timingInfo,
1043
+ // fetchParams’s request’s URL, fetchParams’s request’s initiator type, global, cacheState, bodyInfo,
1044
+ // and responseStatus.
1045
+ if (fetchParams.request.initiatorType != null) {
1046
+ // TODO: update markresourcetiming
1047
+ markResourceTiming(timingInfo, fetchParams.request.url.href, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus)
1048
+ }
1049
+ }
1050
+
1051
+ // 4. Let processResponseEndOfBodyTask be the following steps:
1052
+ const processResponseEndOfBodyTask = () => {
1053
+ // 1. Set fetchParams’s request’s done flag.
1054
+ fetchParams.request.done = true
1055
+
1056
+ // 2. If fetchParams’s process response end-of-body is non-null, then run fetchParams’s process
1057
+ // response end-of-body given response.
1058
+ if (fetchParams.processResponseEndOfBody != null) {
1059
+ queueMicrotask(() => fetchParams.processResponseEndOfBody(response))
1060
+ }
1061
+
1062
+ // 3. If fetchParams’s request’s initiator type is non-null and fetchParams’s request’s client’s
1063
+ // global object is fetchParams’s task destination, then run fetchParams’s controller’s report
1064
+ // timing steps given fetchParams’s request’s client’s global object.
1065
+ if (fetchParams.request.initiatorType != null) {
1066
+ fetchParams.controller.reportTimingSteps()
1067
+ }
1068
+ }
1069
+
1070
+ // 5. Queue a fetch task to run processResponseEndOfBodyTask with fetchParams’s task destination
1071
+ queueMicrotask(() => processResponseEndOfBodyTask())
1072
+ }
1073
+
1074
+ // 4. If fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s
1075
+ // process response given response, with fetchParams’s task destination.
1076
+ if (fetchParams.processResponse != null) {
1077
+ queueMicrotask(() => {
1078
+ fetchParams.processResponse(response)
1079
+ fetchParams.processResponse = null
1080
+ })
1081
+ }
1082
+
1083
+ // 5. Let internalResponse be response, if response is a network error; otherwise response’s internal response.
1084
+ const internalResponse = response.type === 'error' ? response : (response.internalResponse ?? response)
1085
+
1086
+ // 6. If internalResponse’s body is null, then run processResponseEndOfBody.
1087
+ // 7. Otherwise:
1088
+ if (internalResponse.body == null) {
1089
+ processResponseEndOfBody()
1090
+ } else {
1091
+ // mcollina: all the following steps of the specs are skipped.
1092
+ // The internal transform stream is not needed.
1093
+ // See https://github.com/nodejs/undici/pull/3093#issuecomment-2050198541
1094
+
1095
+ // 1. Let transformStream be a new TransformStream.
1096
+ // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, enqueues chunk in transformStream.
1097
+ // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm and flushAlgorithm
1098
+ // set to processResponseEndOfBody.
1099
+ // 4. Set internalResponse’s body’s stream to the result of internalResponse’s body’s stream piped through transformStream.
1100
+
1101
+ finished(internalResponse.body.stream, () => {
1102
+ processResponseEndOfBody()
1103
+ })
1104
+ }
1105
+ }
1106
+
1107
+ // https://fetch.spec.whatwg.org/#http-fetch
1108
+ async function httpFetch (fetchParams) {
1109
+ // 1. Let request be fetchParams’s request.
1110
+ const request = fetchParams.request
1111
+
1112
+ // 2. Let response be null.
1113
+ let response = null
1114
+
1115
+ // 3. Let actualResponse be null.
1116
+ let actualResponse = null
1117
+
1118
+ // 4. Let timingInfo be fetchParams’s timing info.
1119
+ const timingInfo = fetchParams.timingInfo
1120
+
1121
+ // 5. If request’s service-workers mode is "all", then:
1122
+ if (request.serviceWorkers === 'all') {
1123
+ // TODO
1124
+ }
1125
+
1126
+ // 6. If response is null, then:
1127
+ if (response === null) {
1128
+ // 1. If makeCORSPreflight is true and one of these conditions is true:
1129
+ // TODO
1130
+
1131
+ // 2. If request’s redirect mode is "follow", then set request’s
1132
+ // service-workers mode to "none".
1133
+ if (request.redirect === 'follow') {
1134
+ request.serviceWorkers = 'none'
1135
+ }
1136
+
1137
+ // 3. Set response and actualResponse to the result of running
1138
+ // HTTP-network-or-cache fetch given fetchParams.
1139
+ actualResponse = response = await httpNetworkOrCacheFetch(fetchParams)
1140
+
1141
+ // 4. If request’s response tainting is "cors" and a CORS check
1142
+ // for request and response returns failure, then return a network error.
1143
+ if (
1144
+ request.responseTainting === 'cors' &&
1145
+ corsCheck(request, response) === 'failure'
1146
+ ) {
1147
+ return makeNetworkError('cors failure')
1148
+ }
1149
+
1150
+ // 5. If the TAO check for request and response returns failure, then set
1151
+ // request’s timing allow failed flag.
1152
+ if (TAOCheck(request, response) === 'failure') {
1153
+ request.timingAllowFailed = true
1154
+ }
1155
+ }
1156
+
1157
+ // 7. If either request’s response tainting or response’s type
1158
+ // is "opaque", and the cross-origin resource policy check with
1159
+ // request’s origin, request’s client, request’s destination,
1160
+ // and actualResponse returns blocked, then return a network error.
1161
+ if (
1162
+ (request.responseTainting === 'opaque' || response.type === 'opaque') &&
1163
+ crossOriginResourcePolicyCheck(
1164
+ request.origin,
1165
+ request.client,
1166
+ request.destination,
1167
+ actualResponse
1168
+ ) === 'blocked'
1169
+ ) {
1170
+ return makeNetworkError('blocked')
1171
+ }
1172
+
1173
+ // 8. If actualResponse’s status is a redirect status, then:
1174
+ if (redirectStatusSet.has(actualResponse.status)) {
1175
+ // 1. If actualResponse’s status is not 303, request’s body is not null,
1176
+ // and the connection uses HTTP/2, then user agents may, and are even
1177
+ // encouraged to, transmit an RST_STREAM frame.
1178
+ // See, https://github.com/whatwg/fetch/issues/1288
1179
+ if (request.redirect !== 'manual') {
1180
+ fetchParams.controller.connection.destroy(undefined, false)
1181
+ }
1182
+
1183
+ // 2. Switch on request’s redirect mode:
1184
+ if (request.redirect === 'error') {
1185
+ // Set response to a network error.
1186
+ response = makeNetworkError('unexpected redirect')
1187
+ } else if (request.redirect === 'manual') {
1188
+ // Set response to an opaque-redirect filtered response whose internal
1189
+ // response is actualResponse.
1190
+ // NOTE(spec): On the web this would return an `opaqueredirect` response,
1191
+ // but that doesn't make sense server side.
1192
+ // See https://github.com/nodejs/undici/issues/1193.
1193
+ response = actualResponse
1194
+ } else if (request.redirect === 'follow') {
1195
+ // Set response to the result of running HTTP-redirect fetch given
1196
+ // fetchParams and response.
1197
+ response = await httpRedirectFetch(fetchParams, response)
1198
+ } else {
1199
+ assert(false)
1200
+ }
1201
+ }
1202
+
1203
+ // 9. Set response’s timing info to timingInfo.
1204
+ response.timingInfo = timingInfo
1205
+
1206
+ // 10. Return response.
1207
+ return response
1208
+ }
1209
+
1210
+ // https://fetch.spec.whatwg.org/#http-redirect-fetch
1211
+ function httpRedirectFetch (fetchParams, response) {
1212
+ // 1. Let request be fetchParams’s request.
1213
+ const request = fetchParams.request
1214
+
1215
+ // 2. Let actualResponse be response, if response is not a filtered response,
1216
+ // and response’s internal response otherwise.
1217
+ const actualResponse = response.internalResponse
1218
+ ? response.internalResponse
1219
+ : response
1220
+
1221
+ // 3. Let locationURL be actualResponse’s location URL given request’s current
1222
+ // URL’s fragment.
1223
+ let locationURL
1224
+
1225
+ try {
1226
+ locationURL = responseLocationURL(
1227
+ actualResponse,
1228
+ requestCurrentURL(request).hash
1229
+ )
1230
+
1231
+ // 4. If locationURL is null, then return response.
1232
+ if (locationURL == null) {
1233
+ return response
1234
+ }
1235
+ } catch (err) {
1236
+ // 5. If locationURL is failure, then return a network error.
1237
+ return Promise.resolve(makeNetworkError(err))
1238
+ }
1239
+
1240
+ // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network
1241
+ // error.
1242
+ if (!urlIsHttpHttpsScheme(locationURL)) {
1243
+ return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme'))
1244
+ }
1245
+
1246
+ // 7. If request’s redirect count is 20, then return a network error.
1247
+ if (request.redirectCount === 20) {
1248
+ return Promise.resolve(makeNetworkError('redirect count exceeded'))
1249
+ }
1250
+
1251
+ // 8. Increase request’s redirect count by 1.
1252
+ request.redirectCount += 1
1253
+
1254
+ // 9. If request’s mode is "cors", locationURL includes credentials, and
1255
+ // request’s origin is not same origin with locationURL’s origin, then return
1256
+ // a network error.
1257
+ if (
1258
+ request.mode === 'cors' &&
1259
+ (locationURL.username || locationURL.password) &&
1260
+ !sameOrigin(request, locationURL)
1261
+ ) {
1262
+ return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"'))
1263
+ }
1264
+
1265
+ // 10. If request’s response tainting is "cors" and locationURL includes
1266
+ // credentials, then return a network error.
1267
+ if (
1268
+ request.responseTainting === 'cors' &&
1269
+ (locationURL.username || locationURL.password)
1270
+ ) {
1271
+ return Promise.resolve(makeNetworkError(
1272
+ 'URL cannot contain credentials for request mode "cors"'
1273
+ ))
1274
+ }
1275
+
1276
+ // 11. If actualResponse’s status is not 303, request’s body is non-null,
1277
+ // and request’s body’s source is null, then return a network error.
1278
+ if (
1279
+ actualResponse.status !== 303 &&
1280
+ request.body != null &&
1281
+ request.body.source == null
1282
+ ) {
1283
+ return Promise.resolve(makeNetworkError())
1284
+ }
1285
+
1286
+ // 12. If one of the following is true
1287
+ // - actualResponse’s status is 301 or 302 and request’s method is `POST`
1288
+ // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD`
1289
+ if (
1290
+ ([301, 302].includes(actualResponse.status) && request.method === 'POST') ||
1291
+ (actualResponse.status === 303 &&
1292
+ !GET_OR_HEAD.includes(request.method))
1293
+ ) {
1294
+ // then:
1295
+ // 1. Set request’s method to `GET` and request’s body to null.
1296
+ request.method = 'GET'
1297
+ request.body = null
1298
+
1299
+ // 2. For each headerName of request-body-header name, delete headerName from
1300
+ // request’s header list.
1301
+ for (const headerName of requestBodyHeader) {
1302
+ request.headersList.delete(headerName)
1303
+ }
1304
+ }
1305
+
1306
+ // 13. If request’s current URL’s origin is not same origin with locationURL’s
1307
+ // origin, then for each headerName of CORS non-wildcard request-header name,
1308
+ // delete headerName from request’s header list.
1309
+ if (!sameOrigin(requestCurrentURL(request), locationURL)) {
1310
+ // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name
1311
+ request.headersList.delete('authorization', true)
1312
+
1313
+ // https://fetch.spec.whatwg.org/#authentication-entries
1314
+ request.headersList.delete('proxy-authorization', true)
1315
+
1316
+ // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement.
1317
+ request.headersList.delete('cookie', true)
1318
+ request.headersList.delete('host', true)
1319
+ }
1320
+
1321
+ // 14. If request’s body is non-null, then set request’s body to the first return
1322
+ // value of safely extracting request’s body’s source.
1323
+ if (request.body != null) {
1324
+ assert(request.body.source != null)
1325
+ request.body = safelyExtractBody(request.body.source)[0]
1326
+ }
1327
+
1328
+ // 15. Let timingInfo be fetchParams’s timing info.
1329
+ const timingInfo = fetchParams.timingInfo
1330
+
1331
+ // 16. Set timingInfo’s redirect end time and post-redirect start time to the
1332
+ // coarsened shared current time given fetchParams’s cross-origin isolated
1333
+ // capability.
1334
+ timingInfo.redirectEndTime = timingInfo.postRedirectStartTime =
1335
+ coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability)
1336
+
1337
+ // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s
1338
+ // redirect start time to timingInfo’s start time.
1339
+ if (timingInfo.redirectStartTime === 0) {
1340
+ timingInfo.redirectStartTime = timingInfo.startTime
1341
+ }
1342
+
1343
+ // 18. Append locationURL to request’s URL list.
1344
+ request.urlList.push(locationURL)
1345
+
1346
+ // 19. Invoke set request’s referrer policy on redirect on request and
1347
+ // actualResponse.
1348
+ setRequestReferrerPolicyOnRedirect(request, actualResponse)
1349
+
1350
+ // 20. Return the result of running main fetch given fetchParams and true.
1351
+ return mainFetch(fetchParams, true)
1352
+ }
1353
+
1354
+ // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
1355
+ async function httpNetworkOrCacheFetch (
1356
+ fetchParams,
1357
+ isAuthenticationFetch = false,
1358
+ isNewConnectionFetch = false
1359
+ ) {
1360
+ // 1. Let request be fetchParams’s request.
1361
+ const request = fetchParams.request
1362
+
1363
+ // 2. Let httpFetchParams be null.
1364
+ let httpFetchParams = null
1365
+
1366
+ // 3. Let httpRequest be null.
1367
+ let httpRequest = null
1368
+
1369
+ // 4. Let response be null.
1370
+ let response = null
1371
+
1372
+ // 5. Let storedResponse be null.
1373
+ // TODO: cache
1374
+
1375
+ // 6. Let httpCache be null.
1376
+ const httpCache = null
1377
+
1378
+ // 7. Let the revalidatingFlag be unset.
1379
+ const revalidatingFlag = false
1380
+
1381
+ // 8. Run these steps, but abort when the ongoing fetch is terminated:
1382
+
1383
+ // 1. If request’s window is "no-window" and request’s redirect mode is
1384
+ // "error", then set httpFetchParams to fetchParams and httpRequest to
1385
+ // request.
1386
+ if (request.window === 'no-window' && request.redirect === 'error') {
1387
+ httpFetchParams = fetchParams
1388
+ httpRequest = request
1389
+ } else {
1390
+ // Otherwise:
1391
+
1392
+ // 1. Set httpRequest to a clone of request.
1393
+ httpRequest = cloneRequest(request)
1394
+
1395
+ // 2. Set httpFetchParams to a copy of fetchParams.
1396
+ httpFetchParams = { ...fetchParams }
1397
+
1398
+ // 3. Set httpFetchParams’s request to httpRequest.
1399
+ httpFetchParams.request = httpRequest
1400
+ }
1401
+
1402
+ // 3. Let includeCredentials be true if one of
1403
+ const includeCredentials =
1404
+ request.credentials === 'include' ||
1405
+ (request.credentials === 'same-origin' &&
1406
+ request.responseTainting === 'basic')
1407
+
1408
+ // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s
1409
+ // body is non-null; otherwise null.
1410
+ const contentLength = httpRequest.body ? httpRequest.body.length : null
1411
+
1412
+ // 5. Let contentLengthHeaderValue be null.
1413
+ let contentLengthHeaderValue = null
1414
+
1415
+ // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or
1416
+ // `PUT`, then set contentLengthHeaderValue to `0`.
1417
+ if (
1418
+ httpRequest.body == null &&
1419
+ ['POST', 'PUT'].includes(httpRequest.method)
1420
+ ) {
1421
+ contentLengthHeaderValue = '0'
1422
+ }
1423
+
1424
+ // 7. If contentLength is non-null, then set contentLengthHeaderValue to
1425
+ // contentLength, serialized and isomorphic encoded.
1426
+ if (contentLength != null) {
1427
+ contentLengthHeaderValue = isomorphicEncode(`${contentLength}`)
1428
+ }
1429
+
1430
+ // 8. If contentLengthHeaderValue is non-null, then append
1431
+ // `Content-Length`/contentLengthHeaderValue to httpRequest’s header
1432
+ // list.
1433
+ if (contentLengthHeaderValue != null) {
1434
+ httpRequest.headersList.append('content-length', contentLengthHeaderValue, true)
1435
+ }
1436
+
1437
+ // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`,
1438
+ // contentLengthHeaderValue) to httpRequest’s header list.
1439
+
1440
+ // 10. If contentLength is non-null and httpRequest’s keepalive is true,
1441
+ // then:
1442
+ if (contentLength != null && httpRequest.keepalive) {
1443
+ // NOTE: keepalive is a noop outside of browser context.
1444
+ }
1445
+
1446
+ // 11. If httpRequest’s referrer is a URL, then append
1447
+ // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded,
1448
+ // to httpRequest’s header list.
1449
+ if (httpRequest.referrer instanceof URL) {
1450
+ httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href), true)
1451
+ }
1452
+
1453
+ // 12. Append a request `Origin` header for httpRequest.
1454
+ appendRequestOriginHeader(httpRequest)
1455
+
1456
+ // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA]
1457
+ appendFetchMetadata(httpRequest)
1458
+
1459
+ // 14. If httpRequest’s header list does not contain `User-Agent`, then
1460
+ // user agents should append `User-Agent`/default `User-Agent` value to
1461
+ // httpRequest’s header list.
1462
+ if (!httpRequest.headersList.contains('user-agent', true)) {
1463
+ httpRequest.headersList.append('user-agent', defaultUserAgent)
1464
+ }
1465
+
1466
+ // 15. If httpRequest’s cache mode is "default" and httpRequest’s header
1467
+ // list contains `If-Modified-Since`, `If-None-Match`,
1468
+ // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set
1469
+ // httpRequest’s cache mode to "no-store".
1470
+ if (
1471
+ httpRequest.cache === 'default' &&
1472
+ (httpRequest.headersList.contains('if-modified-since', true) ||
1473
+ httpRequest.headersList.contains('if-none-match', true) ||
1474
+ httpRequest.headersList.contains('if-unmodified-since', true) ||
1475
+ httpRequest.headersList.contains('if-match', true) ||
1476
+ httpRequest.headersList.contains('if-range', true))
1477
+ ) {
1478
+ httpRequest.cache = 'no-store'
1479
+ }
1480
+
1481
+ // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent
1482
+ // no-cache cache-control header modification flag is unset, and
1483
+ // httpRequest’s header list does not contain `Cache-Control`, then append
1484
+ // `Cache-Control`/`max-age=0` to httpRequest’s header list.
1485
+ if (
1486
+ httpRequest.cache === 'no-cache' &&
1487
+ !httpRequest.preventNoCacheCacheControlHeaderModification &&
1488
+ !httpRequest.headersList.contains('cache-control', true)
1489
+ ) {
1490
+ httpRequest.headersList.append('cache-control', 'max-age=0', true)
1491
+ }
1492
+
1493
+ // 17. If httpRequest’s cache mode is "no-store" or "reload", then:
1494
+ if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') {
1495
+ // 1. If httpRequest’s header list does not contain `Pragma`, then append
1496
+ // `Pragma`/`no-cache` to httpRequest’s header list.
1497
+ if (!httpRequest.headersList.contains('pragma', true)) {
1498
+ httpRequest.headersList.append('pragma', 'no-cache', true)
1499
+ }
1500
+
1501
+ // 2. If httpRequest’s header list does not contain `Cache-Control`,
1502
+ // then append `Cache-Control`/`no-cache` to httpRequest’s header list.
1503
+ if (!httpRequest.headersList.contains('cache-control', true)) {
1504
+ httpRequest.headersList.append('cache-control', 'no-cache', true)
1505
+ }
1506
+ }
1507
+
1508
+ // 18. If httpRequest’s header list contains `Range`, then append
1509
+ // `Accept-Encoding`/`identity` to httpRequest’s header list.
1510
+ if (httpRequest.headersList.contains('range', true)) {
1511
+ httpRequest.headersList.append('accept-encoding', 'identity', true)
1512
+ }
1513
+
1514
+ // 19. Modify httpRequest’s header list per HTTP. Do not append a given
1515
+ // header if httpRequest’s header list contains that header’s name.
1516
+ // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129
1517
+ if (!httpRequest.headersList.contains('accept-encoding', true)) {
1518
+ if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) {
1519
+ httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate', true)
1520
+ } else {
1521
+ httpRequest.headersList.append('accept-encoding', 'gzip, deflate', true)
1522
+ }
1523
+ }
1524
+
1525
+ httpRequest.headersList.delete('host', true)
1526
+
1527
+ // 20. If includeCredentials is true, then:
1528
+ if (includeCredentials) {
1529
+ // 1. If the user agent is not configured to block cookies for httpRequest
1530
+ // (see section 7 of [COOKIES]), then:
1531
+ // TODO: credentials
1532
+ // 2. If httpRequest’s header list does not contain `Authorization`, then:
1533
+ // TODO: credentials
1534
+ }
1535
+
1536
+ // 21. If there’s a proxy-authentication entry, use it as appropriate.
1537
+ // TODO: proxy-authentication
1538
+
1539
+ // 22. Set httpCache to the result of determining the HTTP cache
1540
+ // partition, given httpRequest.
1541
+ // TODO: cache
1542
+
1543
+ // 23. If httpCache is null, then set httpRequest’s cache mode to
1544
+ // "no-store".
1545
+ if (httpCache == null) {
1546
+ httpRequest.cache = 'no-store'
1547
+ }
1548
+
1549
+ // 24. If httpRequest’s cache mode is neither "no-store" nor "reload",
1550
+ // then:
1551
+ if (httpRequest.cache !== 'no-store' && httpRequest.cache !== 'reload') {
1552
+ // TODO: cache
1553
+ }
1554
+
1555
+ // 9. If aborted, then return the appropriate network error for fetchParams.
1556
+ // TODO
1557
+
1558
+ // 10. If response is null, then:
1559
+ if (response == null) {
1560
+ // 1. If httpRequest’s cache mode is "only-if-cached", then return a
1561
+ // network error.
1562
+ if (httpRequest.cache === 'only-if-cached') {
1563
+ return makeNetworkError('only if cached')
1564
+ }
1565
+
1566
+ // 2. Let forwardResponse be the result of running HTTP-network fetch
1567
+ // given httpFetchParams, includeCredentials, and isNewConnectionFetch.
1568
+ const forwardResponse = await httpNetworkFetch(
1569
+ httpFetchParams,
1570
+ includeCredentials,
1571
+ isNewConnectionFetch
1572
+ )
1573
+
1574
+ // 3. If httpRequest’s method is unsafe and forwardResponse’s status is
1575
+ // in the range 200 to 399, inclusive, invalidate appropriate stored
1576
+ // responses in httpCache, as per the "Invalidation" chapter of HTTP
1577
+ // Caching, and set storedResponse to null. [HTTP-CACHING]
1578
+ if (
1579
+ !safeMethodsSet.has(httpRequest.method) &&
1580
+ forwardResponse.status >= 200 &&
1581
+ forwardResponse.status <= 399
1582
+ ) {
1583
+ // TODO: cache
1584
+ }
1585
+
1586
+ // 4. If the revalidatingFlag is set and forwardResponse’s status is 304,
1587
+ // then:
1588
+ if (revalidatingFlag && forwardResponse.status === 304) {
1589
+ // TODO: cache
1590
+ }
1591
+
1592
+ // 5. If response is null, then:
1593
+ if (response == null) {
1594
+ // 1. Set response to forwardResponse.
1595
+ response = forwardResponse
1596
+
1597
+ // 2. Store httpRequest and forwardResponse in httpCache, as per the
1598
+ // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING]
1599
+ // TODO: cache
1600
+ }
1601
+ }
1602
+
1603
+ // 11. Set response’s URL list to a clone of httpRequest’s URL list.
1604
+ response.urlList = [...httpRequest.urlList]
1605
+
1606
+ // 12. If httpRequest’s header list contains `Range`, then set response’s
1607
+ // range-requested flag.
1608
+ if (httpRequest.headersList.contains('range', true)) {
1609
+ response.rangeRequested = true
1610
+ }
1611
+
1612
+ // 13. Set response’s request-includes-credentials to includeCredentials.
1613
+ response.requestIncludesCredentials = includeCredentials
1614
+
1615
+ // 14. If response’s status is 401, httpRequest’s response tainting is not
1616
+ // "cors", includeCredentials is true, and request’s window is an environment
1617
+ // settings object, then:
1618
+ // TODO
1619
+
1620
+ // 15. If response’s status is 407, then:
1621
+ if (response.status === 407) {
1622
+ // 1. If request’s window is "no-window", then return a network error.
1623
+ if (request.window === 'no-window') {
1624
+ return makeNetworkError()
1625
+ }
1626
+
1627
+ // 2. ???
1628
+
1629
+ // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams.
1630
+ if (isCancelled(fetchParams)) {
1631
+ return makeAppropriateNetworkError(fetchParams)
1632
+ }
1633
+
1634
+ // 4. Prompt the end user as appropriate in request’s window and store
1635
+ // the result as a proxy-authentication entry. [HTTP-AUTH]
1636
+ // TODO: Invoke some kind of callback?
1637
+
1638
+ // 5. Set response to the result of running HTTP-network-or-cache fetch given
1639
+ // fetchParams.
1640
+ // TODO
1641
+ return makeNetworkError('proxy authentication required')
1642
+ }
1643
+
1644
+ // 16. If all of the following are true
1645
+ if (
1646
+ // response’s status is 421
1647
+ response.status === 421 &&
1648
+ // isNewConnectionFetch is false
1649
+ !isNewConnectionFetch &&
1650
+ // request’s body is null, or request’s body is non-null and request’s body’s source is non-null
1651
+ (request.body == null || request.body.source != null)
1652
+ ) {
1653
+ // then:
1654
+
1655
+ // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams.
1656
+ if (isCancelled(fetchParams)) {
1657
+ return makeAppropriateNetworkError(fetchParams)
1658
+ }
1659
+
1660
+ // 2. Set response to the result of running HTTP-network-or-cache
1661
+ // fetch given fetchParams, isAuthenticationFetch, and true.
1662
+
1663
+ // TODO (spec): The spec doesn't specify this but we need to cancel
1664
+ // the active response before we can start a new one.
1665
+ // https://github.com/whatwg/fetch/issues/1293
1666
+ fetchParams.controller.connection.destroy()
1667
+
1668
+ response = await httpNetworkOrCacheFetch(
1669
+ fetchParams,
1670
+ isAuthenticationFetch,
1671
+ true
1672
+ )
1673
+ }
1674
+
1675
+ // 17. If isAuthenticationFetch is true, then create an authentication entry
1676
+ if (isAuthenticationFetch) {
1677
+ // TODO
1678
+ }
1679
+
1680
+ // 18. Return response.
1681
+ return response
1682
+ }
1683
+
1684
+ // https://fetch.spec.whatwg.org/#http-network-fetch
1685
+ async function httpNetworkFetch (
1686
+ fetchParams,
1687
+ includeCredentials = false,
1688
+ forceNewConnection = false
1689
+ ) {
1690
+ assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed)
1691
+
1692
+ fetchParams.controller.connection = {
1693
+ abort: null,
1694
+ destroyed: false,
1695
+ destroy (err, abort = true) {
1696
+ if (!this.destroyed) {
1697
+ this.destroyed = true
1698
+ if (abort) {
1699
+ this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError'))
1700
+ }
1701
+ }
1702
+ }
1703
+ }
1704
+
1705
+ // 1. Let request be fetchParams’s request.
1706
+ const request = fetchParams.request
1707
+
1708
+ // 2. Let response be null.
1709
+ let response = null
1710
+
1711
+ // 3. Let timingInfo be fetchParams’s timing info.
1712
+ const timingInfo = fetchParams.timingInfo
1713
+
1714
+ // 4. Let httpCache be the result of determining the HTTP cache partition,
1715
+ // given request.
1716
+ // TODO: cache
1717
+ const httpCache = null
1718
+
1719
+ // 5. If httpCache is null, then set request’s cache mode to "no-store".
1720
+ if (httpCache == null) {
1721
+ request.cache = 'no-store'
1722
+ }
1723
+
1724
+ // 6. Let networkPartitionKey be the result of determining the network
1725
+ // partition key given request.
1726
+ // TODO
1727
+
1728
+ // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise
1729
+ // "no".
1730
+ const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars
1731
+
1732
+ // 8. Switch on request’s mode:
1733
+ if (request.mode === 'websocket') {
1734
+ // Let connection be the result of obtaining a WebSocket connection,
1735
+ // given request’s current URL.
1736
+ // TODO
1737
+ } else {
1738
+ // Let connection be the result of obtaining a connection, given
1739
+ // networkPartitionKey, request’s current URL’s origin,
1740
+ // includeCredentials, and forceNewConnection.
1741
+ // TODO
1742
+ }
1743
+
1744
+ // 9. Run these steps, but abort when the ongoing fetch is terminated:
1745
+
1746
+ // 1. If connection is failure, then return a network error.
1747
+
1748
+ // 2. Set timingInfo’s final connection timing info to the result of
1749
+ // calling clamp and coarsen connection timing info with connection’s
1750
+ // timing info, timingInfo’s post-redirect start time, and fetchParams’s
1751
+ // cross-origin isolated capability.
1752
+
1753
+ // 3. If connection is not an HTTP/2 connection, request’s body is non-null,
1754
+ // and request’s body’s source is null, then append (`Transfer-Encoding`,
1755
+ // `chunked`) to request’s header list.
1756
+
1757
+ // 4. Set timingInfo’s final network-request start time to the coarsened
1758
+ // shared current time given fetchParams’s cross-origin isolated
1759
+ // capability.
1760
+
1761
+ // 5. Set response to the result of making an HTTP request over connection
1762
+ // using request with the following caveats:
1763
+
1764
+ // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS]
1765
+ // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH]
1766
+
1767
+ // - If request’s body is non-null, and request’s body’s source is null,
1768
+ // then the user agent may have a buffer of up to 64 kibibytes and store
1769
+ // a part of request’s body in that buffer. If the user agent reads from
1770
+ // request’s body beyond that buffer’s size and the user agent needs to
1771
+ // resend request, then instead return a network error.
1772
+
1773
+ // - Set timingInfo’s final network-response start time to the coarsened
1774
+ // shared current time given fetchParams’s cross-origin isolated capability,
1775
+ // immediately after the user agent’s HTTP parser receives the first byte
1776
+ // of the response (e.g., frame header bytes for HTTP/2 or response status
1777
+ // line for HTTP/1.x).
1778
+
1779
+ // - Wait until all the headers are transmitted.
1780
+
1781
+ // - Any responses whose status is in the range 100 to 199, inclusive,
1782
+ // and is not 101, are to be ignored, except for the purposes of setting
1783
+ // timingInfo’s final network-response start time above.
1784
+
1785
+ // - If request’s header list contains `Transfer-Encoding`/`chunked` and
1786
+ // response is transferred via HTTP/1.0 or older, then return a network
1787
+ // error.
1788
+
1789
+ // - If the HTTP request results in a TLS client certificate dialog, then:
1790
+
1791
+ // 1. If request’s window is an environment settings object, make the
1792
+ // dialog available in request’s window.
1793
+
1794
+ // 2. Otherwise, return a network error.
1795
+
1796
+ // To transmit request’s body body, run these steps:
1797
+ let requestBody = null
1798
+ // 1. If body is null and fetchParams’s process request end-of-body is
1799
+ // non-null, then queue a fetch task given fetchParams’s process request
1800
+ // end-of-body and fetchParams’s task destination.
1801
+ if (request.body == null && fetchParams.processRequestEndOfBody) {
1802
+ queueMicrotask(() => fetchParams.processRequestEndOfBody())
1803
+ } else if (request.body != null) {
1804
+ // 2. Otherwise, if body is non-null:
1805
+
1806
+ // 1. Let processBodyChunk given bytes be these steps:
1807
+ const processBodyChunk = async function * (bytes) {
1808
+ // 1. If the ongoing fetch is terminated, then abort these steps.
1809
+ if (isCancelled(fetchParams)) {
1810
+ return
1811
+ }
1812
+
1813
+ // 2. Run this step in parallel: transmit bytes.
1814
+ yield bytes
1815
+
1816
+ // 3. If fetchParams’s process request body is non-null, then run
1817
+ // fetchParams’s process request body given bytes’s length.
1818
+ fetchParams.processRequestBodyChunkLength?.(bytes.byteLength)
1819
+ }
1820
+
1821
+ // 2. Let processEndOfBody be these steps:
1822
+ const processEndOfBody = () => {
1823
+ // 1. If fetchParams is canceled, then abort these steps.
1824
+ if (isCancelled(fetchParams)) {
1825
+ return
1826
+ }
1827
+
1828
+ // 2. If fetchParams’s process request end-of-body is non-null,
1829
+ // then run fetchParams’s process request end-of-body.
1830
+ if (fetchParams.processRequestEndOfBody) {
1831
+ fetchParams.processRequestEndOfBody()
1832
+ }
1833
+ }
1834
+
1835
+ // 3. Let processBodyError given e be these steps:
1836
+ const processBodyError = (e) => {
1837
+ // 1. If fetchParams is canceled, then abort these steps.
1838
+ if (isCancelled(fetchParams)) {
1839
+ return
1840
+ }
1841
+
1842
+ // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller.
1843
+ if (e.name === 'AbortError') {
1844
+ fetchParams.controller.abort()
1845
+ } else {
1846
+ fetchParams.controller.terminate(e)
1847
+ }
1848
+ }
1849
+
1850
+ // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody,
1851
+ // processBodyError, and fetchParams’s task destination.
1852
+ requestBody = (async function * () {
1853
+ try {
1854
+ for await (const bytes of request.body.stream) {
1855
+ yield * processBodyChunk(bytes)
1856
+ }
1857
+ processEndOfBody()
1858
+ } catch (err) {
1859
+ processBodyError(err)
1860
+ }
1861
+ })()
1862
+ }
1863
+
1864
+ try {
1865
+ // socket is only provided for websockets
1866
+ const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody })
1867
+
1868
+ if (socket) {
1869
+ response = makeResponse({ status, statusText, headersList, socket })
1870
+ } else {
1871
+ const iterator = body[Symbol.asyncIterator]()
1872
+ fetchParams.controller.next = () => iterator.next()
1873
+
1874
+ response = makeResponse({ status, statusText, headersList })
1875
+ }
1876
+ } catch (err) {
1877
+ // 10. If aborted, then:
1878
+ if (err.name === 'AbortError') {
1879
+ // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame.
1880
+ fetchParams.controller.connection.destroy()
1881
+
1882
+ // 2. Return the appropriate network error for fetchParams.
1883
+ return makeAppropriateNetworkError(fetchParams, err)
1884
+ }
1885
+
1886
+ return makeNetworkError(err)
1887
+ }
1888
+
1889
+ // 11. Let pullAlgorithm be an action that resumes the ongoing fetch
1890
+ // if it is suspended.
1891
+ const pullAlgorithm = async () => {
1892
+ await fetchParams.controller.resume()
1893
+ }
1894
+
1895
+ // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s
1896
+ // controller with reason, given reason.
1897
+ const cancelAlgorithm = (reason) => {
1898
+ // If the aborted fetch was already terminated, then we do not
1899
+ // need to do anything.
1900
+ if (!isCancelled(fetchParams)) {
1901
+ fetchParams.controller.abort(reason)
1902
+ }
1903
+ }
1904
+
1905
+ // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by
1906
+ // the user agent.
1907
+ // TODO
1908
+
1909
+ // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object
1910
+ // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent.
1911
+ // TODO
1912
+
1913
+ // 15. Let stream be a new ReadableStream.
1914
+ // 16. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm,
1915
+ // cancelAlgorithm set to cancelAlgorithm.
1916
+ const stream = new ReadableStream(
1917
+ {
1918
+ async start (controller) {
1919
+ fetchParams.controller.controller = controller
1920
+ },
1921
+ async pull (controller) {
1922
+ await pullAlgorithm(controller)
1923
+ },
1924
+ async cancel (reason) {
1925
+ await cancelAlgorithm(reason)
1926
+ },
1927
+ type: 'bytes'
1928
+ }
1929
+ )
1930
+
1931
+ // 17. Run these steps, but abort when the ongoing fetch is terminated:
1932
+
1933
+ // 1. Set response’s body to a new body whose stream is stream.
1934
+ response.body = { stream, source: null, length: null }
1935
+
1936
+ // 2. If response is not a network error and request’s cache mode is
1937
+ // not "no-store", then update response in httpCache for request.
1938
+ // TODO
1939
+
1940
+ // 3. If includeCredentials is true and the user agent is not configured
1941
+ // to block cookies for request (see section 7 of [COOKIES]), then run the
1942
+ // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on
1943
+ // the value of each header whose name is a byte-case-insensitive match for
1944
+ // `Set-Cookie` in response’s header list, if any, and request’s current URL.
1945
+ // TODO
1946
+
1947
+ // 18. If aborted, then:
1948
+ // TODO
1949
+
1950
+ // 19. Run these steps in parallel:
1951
+
1952
+ // 1. Run these steps, but abort when fetchParams is canceled:
1953
+ fetchParams.controller.onAborted = onAborted
1954
+ fetchParams.controller.on('terminated', onAborted)
1955
+ fetchParams.controller.resume = async () => {
1956
+ // 1. While true
1957
+ while (true) {
1958
+ // 1-3. See onData...
1959
+
1960
+ // 4. Set bytes to the result of handling content codings given
1961
+ // codings and bytes.
1962
+ let bytes
1963
+ let isFailure
1964
+ try {
1965
+ const { done, value } = await fetchParams.controller.next()
1966
+
1967
+ if (isAborted(fetchParams)) {
1968
+ break
1969
+ }
1970
+
1971
+ bytes = done ? undefined : value
1972
+ } catch (err) {
1973
+ if (fetchParams.controller.ended && !timingInfo.encodedBodySize) {
1974
+ // zlib doesn't like empty streams.
1975
+ bytes = undefined
1976
+ } else {
1977
+ bytes = err
1978
+
1979
+ // err may be propagated from the result of calling readablestream.cancel,
1980
+ // which might not be an error. https://github.com/nodejs/undici/issues/2009
1981
+ isFailure = true
1982
+ }
1983
+ }
1984
+
1985
+ if (bytes === undefined) {
1986
+ // 2. Otherwise, if the bytes transmission for response’s message
1987
+ // body is done normally and stream is readable, then close
1988
+ // stream, finalize response for fetchParams and response, and
1989
+ // abort these in-parallel steps.
1990
+ readableStreamClose(fetchParams.controller.controller)
1991
+
1992
+ finalizeResponse(fetchParams, response)
1993
+
1994
+ return
1995
+ }
1996
+
1997
+ // 5. Increase timingInfo’s decoded body size by bytes’s length.
1998
+ timingInfo.decodedBodySize += bytes?.byteLength ?? 0
1999
+
2000
+ // 6. If bytes is failure, then terminate fetchParams’s controller.
2001
+ if (isFailure) {
2002
+ fetchParams.controller.terminate(bytes)
2003
+ return
2004
+ }
2005
+
2006
+ // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes
2007
+ // into stream.
2008
+ const buffer = new Uint8Array(bytes)
2009
+ if (buffer.byteLength) {
2010
+ fetchParams.controller.controller.enqueue(buffer)
2011
+ }
2012
+
2013
+ // 8. If stream is errored, then terminate the ongoing fetch.
2014
+ if (isErrored(stream)) {
2015
+ fetchParams.controller.terminate()
2016
+ return
2017
+ }
2018
+
2019
+ // 9. If stream doesn’t need more data ask the user agent to suspend
2020
+ // the ongoing fetch.
2021
+ if (fetchParams.controller.controller.desiredSize <= 0) {
2022
+ return
2023
+ }
2024
+ }
2025
+ }
2026
+
2027
+ // 2. If aborted, then:
2028
+ function onAborted (reason) {
2029
+ // 2. If fetchParams is aborted, then:
2030
+ if (isAborted(fetchParams)) {
2031
+ // 1. Set response’s aborted flag.
2032
+ response.aborted = true
2033
+
2034
+ // 2. If stream is readable, then error stream with the result of
2035
+ // deserialize a serialized abort reason given fetchParams’s
2036
+ // controller’s serialized abort reason and an
2037
+ // implementation-defined realm.
2038
+ if (isReadable(stream)) {
2039
+ fetchParams.controller.controller.error(
2040
+ fetchParams.controller.serializedAbortReason
2041
+ )
2042
+ }
2043
+ } else {
2044
+ // 3. Otherwise, if stream is readable, error stream with a TypeError.
2045
+ if (isReadable(stream)) {
2046
+ fetchParams.controller.controller.error(new TypeError('terminated', {
2047
+ cause: isErrorLike(reason) ? reason : undefined
2048
+ }))
2049
+ }
2050
+ }
2051
+
2052
+ // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame.
2053
+ // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so.
2054
+ fetchParams.controller.connection.destroy()
2055
+ }
2056
+
2057
+ // 20. Return response.
2058
+ return response
2059
+
2060
+ function dispatch ({ body }) {
2061
+ const url = requestCurrentURL(request)
2062
+ /** @type {import('../..').Agent} */
2063
+ const agent = fetchParams.controller.dispatcher
2064
+
2065
+ return new Promise((resolve, reject) => agent.dispatch(
2066
+ {
2067
+ path: url.pathname + url.search,
2068
+ origin: url.origin,
2069
+ method: request.method,
2070
+ body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
2071
+ headers: request.headersList.entries,
2072
+ maxRedirections: 0,
2073
+ upgrade: request.mode === 'websocket' ? 'websocket' : undefined
2074
+ },
2075
+ {
2076
+ body: null,
2077
+ abort: null,
2078
+
2079
+ onConnect (abort) {
2080
+ // TODO (fix): Do we need connection here?
2081
+ const { connection } = fetchParams.controller
2082
+
2083
+ // Set timingInfo’s final connection timing info to the result of calling clamp and coarsen
2084
+ // connection timing info with connection’s timing info, timingInfo’s post-redirect start
2085
+ // time, and fetchParams’s cross-origin isolated capability.
2086
+ // TODO: implement connection timing
2087
+ timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(undefined, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability)
2088
+
2089
+ if (connection.destroyed) {
2090
+ abort(new DOMException('The operation was aborted.', 'AbortError'))
2091
+ } else {
2092
+ fetchParams.controller.on('terminated', abort)
2093
+ this.abort = connection.abort = abort
2094
+ }
2095
+
2096
+ // Set timingInfo’s final network-request start time to the coarsened shared current time given
2097
+ // fetchParams’s cross-origin isolated capability.
2098
+ timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability)
2099
+ },
2100
+
2101
+ onResponseStarted () {
2102
+ // Set timingInfo’s final network-response start time to the coarsened shared current
2103
+ // time given fetchParams’s cross-origin isolated capability, immediately after the
2104
+ // user agent’s HTTP parser receives the first byte of the response (e.g., frame header
2105
+ // bytes for HTTP/2 or response status line for HTTP/1.x).
2106
+ timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability)
2107
+ },
2108
+
2109
+ onHeaders (status, rawHeaders, resume, statusText) {
2110
+ if (status < 200) {
2111
+ return
2112
+ }
2113
+
2114
+ let location = ''
2115
+
2116
+ const headersList = new HeadersList()
2117
+
2118
+ for (let i = 0; i < rawHeaders.length; i += 2) {
2119
+ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true)
2120
+ }
2121
+ location = headersList.get('location', true)
2122
+
2123
+ this.body = new Readable({ read: resume })
2124
+
2125
+ const decoders = []
2126
+
2127
+ const willFollow = location && request.redirect === 'follow' &&
2128
+ redirectStatusSet.has(status)
2129
+
2130
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
2131
+ if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) {
2132
+ // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1
2133
+ const contentEncoding = headersList.get('content-encoding', true)
2134
+ // "All content-coding values are case-insensitive..."
2135
+ /** @type {string[]} */
2136
+ const codings = contentEncoding ? contentEncoding.toLowerCase().split(',') : []
2137
+
2138
+ // Limit the number of content-encodings to prevent resource exhaustion.
2139
+ // CVE fix similar to urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
2140
+ const maxContentEncodings = 5
2141
+ if (codings.length > maxContentEncodings) {
2142
+ reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`))
2143
+ return true
2144
+ }
2145
+
2146
+ for (let i = codings.length - 1; i >= 0; --i) {
2147
+ const coding = codings[i].trim()
2148
+ // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2
2149
+ if (coding === 'x-gzip' || coding === 'gzip') {
2150
+ decoders.push(zlib.createGunzip({
2151
+ // Be less strict when decoding compressed responses, since sometimes
2152
+ // servers send slightly invalid responses that are still accepted
2153
+ // by common browsers.
2154
+ // Always using Z_SYNC_FLUSH is what cURL does.
2155
+ flush: zlib.constants.Z_SYNC_FLUSH,
2156
+ finishFlush: zlib.constants.Z_SYNC_FLUSH
2157
+ }))
2158
+ } else if (coding === 'deflate') {
2159
+ decoders.push(createInflate({
2160
+ flush: zlib.constants.Z_SYNC_FLUSH,
2161
+ finishFlush: zlib.constants.Z_SYNC_FLUSH
2162
+ }))
2163
+ } else if (coding === 'br') {
2164
+ decoders.push(zlib.createBrotliDecompress({
2165
+ flush: zlib.constants.BROTLI_OPERATION_FLUSH,
2166
+ finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
2167
+ }))
2168
+ } else {
2169
+ decoders.length = 0
2170
+ break
2171
+ }
2172
+ }
2173
+ }
2174
+
2175
+ const onError = this.onError.bind(this)
2176
+
2177
+ resolve({
2178
+ status,
2179
+ statusText,
2180
+ headersList,
2181
+ body: decoders.length
2182
+ ? pipeline(this.body, ...decoders, (err) => {
2183
+ if (err) {
2184
+ this.onError(err)
2185
+ }
2186
+ }).on('error', onError)
2187
+ : this.body.on('error', onError)
2188
+ })
2189
+
2190
+ return true
2191
+ },
2192
+
2193
+ onData (chunk) {
2194
+ if (fetchParams.controller.dump) {
2195
+ return
2196
+ }
2197
+
2198
+ // 1. If one or more bytes have been transmitted from response’s
2199
+ // message body, then:
2200
+
2201
+ // 1. Let bytes be the transmitted bytes.
2202
+ const bytes = chunk
2203
+
2204
+ // 2. Let codings be the result of extracting header list values
2205
+ // given `Content-Encoding` and response’s header list.
2206
+ // See pullAlgorithm.
2207
+
2208
+ // 3. Increase timingInfo’s encoded body size by bytes’s length.
2209
+ timingInfo.encodedBodySize += bytes.byteLength
2210
+
2211
+ // 4. See pullAlgorithm...
2212
+
2213
+ return this.body.push(bytes)
2214
+ },
2215
+
2216
+ onComplete () {
2217
+ if (this.abort) {
2218
+ fetchParams.controller.off('terminated', this.abort)
2219
+ }
2220
+
2221
+ if (fetchParams.controller.onAborted) {
2222
+ fetchParams.controller.off('terminated', fetchParams.controller.onAborted)
2223
+ }
2224
+
2225
+ fetchParams.controller.ended = true
2226
+
2227
+ this.body.push(null)
2228
+ },
2229
+
2230
+ onError (error) {
2231
+ if (this.abort) {
2232
+ fetchParams.controller.off('terminated', this.abort)
2233
+ }
2234
+
2235
+ this.body?.destroy(error)
2236
+
2237
+ fetchParams.controller.terminate(error)
2238
+
2239
+ reject(error)
2240
+ },
2241
+
2242
+ onUpgrade (status, rawHeaders, socket) {
2243
+ if (status !== 101) {
2244
+ return
2245
+ }
2246
+
2247
+ const headersList = new HeadersList()
2248
+
2249
+ for (let i = 0; i < rawHeaders.length; i += 2) {
2250
+ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString('latin1'), true)
2251
+ }
2252
+
2253
+ resolve({
2254
+ status,
2255
+ statusText: STATUS_CODES[status],
2256
+ headersList,
2257
+ socket
2258
+ })
2259
+
2260
+ return true
2261
+ }
2262
+ }
2263
+ ))
2264
+ }
2265
+ }
2266
+
2267
+ module.exports = {
2268
+ fetch,
2269
+ Fetch,
2270
+ fetching,
2271
+ finalizeAndReportTiming
2272
+ }