@xrkseek/harness 0.2.4 → 0.2.6

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 (309) hide show
  1. package/node_modules/@xrkseek/core-tools/dist/index.d.ts +1 -0
  2. package/node_modules/@xrkseek/core-tools/dist/index.d.ts.map +1 -1
  3. package/node_modules/@xrkseek/core-tools/dist/index.js +1 -0
  4. package/node_modules/@xrkseek/core-tools/dist/index.js.map +1 -1
  5. package/node_modules/@xrkseek/core-tools/dist/settings-tools.d.ts +37 -0
  6. package/node_modules/@xrkseek/core-tools/dist/settings-tools.d.ts.map +1 -0
  7. package/node_modules/@xrkseek/core-tools/dist/settings-tools.js +161 -0
  8. package/node_modules/@xrkseek/core-tools/dist/settings-tools.js.map +1 -0
  9. package/node_modules/@xrkseek/core-tools/dist/std-tools.d.ts +4 -1
  10. package/node_modules/@xrkseek/core-tools/dist/std-tools.d.ts.map +1 -1
  11. package/node_modules/@xrkseek/core-tools/dist/std-tools.js +6 -1
  12. package/node_modules/@xrkseek/core-tools/dist/std-tools.js.map +1 -1
  13. package/node_modules/@xrkseek/exec-fs/dist/read-image.d.ts.map +1 -1
  14. package/node_modules/@xrkseek/exec-fs/dist/read-image.js +20 -2
  15. package/node_modules/@xrkseek/exec-fs/dist/read-image.js.map +1 -1
  16. package/node_modules/@xrkseek/preset-harness/dist/tsconfig.tsbuildinfo +1 -1
  17. package/node_modules/@xrkseek/preset-minimal/dist/tsconfig.tsbuildinfo +1 -1
  18. package/node_modules/@xrkseek/preset-server/dist/tsconfig.tsbuildinfo +1 -1
  19. package/node_modules/@xrkseek/server-config/dist/index.d.ts +2 -2
  20. package/node_modules/@xrkseek/server-config/dist/index.d.ts.map +1 -1
  21. package/node_modules/@xrkseek/server-config/dist/index.js +3 -2
  22. package/node_modules/@xrkseek/server-config/dist/index.js.map +1 -1
  23. package/node_modules/@xrkseek/server-config/dist/mcp-servers.d.ts +12 -1
  24. package/node_modules/@xrkseek/server-config/dist/mcp-servers.d.ts.map +1 -1
  25. package/node_modules/@xrkseek/server-config/dist/mcp-servers.js +56 -1
  26. package/node_modules/@xrkseek/server-config/dist/mcp-servers.js.map +1 -1
  27. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.d.ts.map +1 -1
  28. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js +17 -1
  29. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js.map +1 -1
  30. package/node_modules/@xrkseek/server-face/dist/context.d.ts +16 -0
  31. package/node_modules/@xrkseek/server-face/dist/context.d.ts.map +1 -1
  32. package/node_modules/@xrkseek/server-face/dist/dispatch.d.ts.map +1 -1
  33. package/node_modules/@xrkseek/server-face/dist/dispatch.js +5 -1
  34. package/node_modules/@xrkseek/server-face/dist/dispatch.js.map +1 -1
  35. package/node_modules/@xrkseek/server-face/dist/face-schema.d.ts.map +1 -1
  36. package/node_modules/@xrkseek/server-face/dist/face-schema.js +2 -0
  37. package/node_modules/@xrkseek/server-face/dist/face-schema.js.map +1 -1
  38. package/node_modules/@xrkseek/server-face/dist/handlers/host.d.ts.map +1 -1
  39. package/node_modules/@xrkseek/server-face/dist/handlers/host.js +2 -0
  40. package/node_modules/@xrkseek/server-face/dist/handlers/host.js.map +1 -1
  41. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.d.ts +8 -0
  42. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.d.ts.map +1 -1
  43. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.js +155 -1
  44. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.js.map +1 -1
  45. package/node_modules/@xrkseek/server-face/dist/handlers/session.d.ts.map +1 -1
  46. package/node_modules/@xrkseek/server-face/dist/handlers/session.js +11 -112
  47. package/node_modules/@xrkseek/server-face/dist/handlers/session.js.map +1 -1
  48. package/node_modules/@xrkseek/server-face/dist/index.d.ts +3 -2
  49. package/node_modules/@xrkseek/server-face/dist/index.d.ts.map +1 -1
  50. package/node_modules/@xrkseek/server-face/dist/index.js +3 -2
  51. package/node_modules/@xrkseek/server-face/dist/index.js.map +1 -1
  52. package/node_modules/@xrkseek/server-face/dist/plugin-inventory.d.ts +29 -3
  53. package/node_modules/@xrkseek/server-face/dist/plugin-inventory.d.ts.map +1 -1
  54. package/node_modules/@xrkseek/server-face/dist/plugin-inventory.js +169 -6
  55. package/node_modules/@xrkseek/server-face/dist/plugin-inventory.js.map +1 -1
  56. package/node_modules/@xrkseek/server-face/dist/presets-catalog.d.ts +9 -7
  57. package/node_modules/@xrkseek/server-face/dist/presets-catalog.d.ts.map +1 -1
  58. package/node_modules/@xrkseek/server-face/dist/presets-catalog.js +7 -17
  59. package/node_modules/@xrkseek/server-face/dist/presets-catalog.js.map +1 -1
  60. package/node_modules/@xrkseek/server-face/dist/runtime.d.ts +10 -0
  61. package/node_modules/@xrkseek/server-face/dist/runtime.d.ts.map +1 -1
  62. package/node_modules/@xrkseek/server-face/dist/runtime.js +8 -0
  63. package/node_modules/@xrkseek/server-face/dist/runtime.js.map +1 -1
  64. package/node_modules/@xrkseek/server-face/dist/select-session-model.d.ts +15 -0
  65. package/node_modules/@xrkseek/server-face/dist/select-session-model.d.ts.map +1 -0
  66. package/node_modules/@xrkseek/server-face/dist/select-session-model.js +117 -0
  67. package/node_modules/@xrkseek/server-face/dist/select-session-model.js.map +1 -0
  68. package/node_modules/@xrkseek/server-face/dist/settings-agent-tools.d.ts +7 -0
  69. package/node_modules/@xrkseek/server-face/dist/settings-agent-tools.d.ts.map +1 -0
  70. package/node_modules/@xrkseek/server-face/dist/settings-agent-tools.js +91 -0
  71. package/node_modules/@xrkseek/server-face/dist/settings-agent-tools.js.map +1 -0
  72. package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts +7 -1
  73. package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts.map +1 -1
  74. package/node_modules/@xrkseek/server-face/dist/settings-credentials.js +85 -26
  75. package/node_modules/@xrkseek/server-face/dist/settings-credentials.js.map +1 -1
  76. package/node_modules/@xrkseek/server-face/dist/slash.d.ts +4 -3
  77. package/node_modules/@xrkseek/server-face/dist/slash.d.ts.map +1 -1
  78. package/node_modules/@xrkseek/server-face/dist/slash.js +191 -20
  79. package/node_modules/@xrkseek/server-face/dist/slash.js.map +1 -1
  80. package/node_modules/@xrkseek/server-host/dist/http-proxy.d.ts +11 -0
  81. package/node_modules/@xrkseek/server-host/dist/http-proxy.d.ts.map +1 -0
  82. package/node_modules/@xrkseek/server-host/dist/http-proxy.js +42 -0
  83. package/node_modules/@xrkseek/server-host/dist/http-proxy.js.map +1 -0
  84. package/node_modules/@xrkseek/server-host/dist/index.d.ts.map +1 -1
  85. package/node_modules/@xrkseek/server-host/dist/index.js +43 -3
  86. package/node_modules/@xrkseek/server-host/dist/index.js.map +1 -1
  87. package/node_modules/@xrkseek/server-host/dist/mcp-wire.d.ts +4 -3
  88. package/node_modules/@xrkseek/server-host/dist/mcp-wire.d.ts.map +1 -1
  89. package/node_modules/@xrkseek/server-host/dist/mcp-wire.js +14 -10
  90. package/node_modules/@xrkseek/server-host/dist/mcp-wire.js.map +1 -1
  91. package/node_modules/@xrkseek/server-host/package.json +57 -56
  92. package/node_modules/@xrkseek/server-http/dist/index.d.ts +1 -0
  93. package/node_modules/@xrkseek/server-http/dist/index.d.ts.map +1 -1
  94. package/node_modules/@xrkseek/server-http/dist/index.js +1 -0
  95. package/node_modules/@xrkseek/server-http/dist/index.js.map +1 -1
  96. package/node_modules/@xrkseek/server-http/dist/xrk/plugin-mutate.d.ts.map +1 -1
  97. package/node_modules/@xrkseek/server-http/dist/xrk/plugin-mutate.js +6 -1
  98. package/node_modules/@xrkseek/server-http/dist/xrk/plugin-mutate.js.map +1 -1
  99. package/node_modules/undici/LICENSE +21 -0
  100. package/node_modules/undici/README.md +741 -0
  101. package/node_modules/undici/docs/docs/api/Agent.md +84 -0
  102. package/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  103. package/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  104. package/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
  105. package/node_modules/undici/docs/docs/api/Client.md +288 -0
  106. package/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  107. package/node_modules/undici/docs/docs/api/Connector.md +115 -0
  108. package/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  109. package/node_modules/undici/docs/docs/api/Cookies.md +128 -0
  110. package/node_modules/undici/docs/docs/api/Debug.md +62 -0
  111. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
  112. package/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
  113. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  114. package/node_modules/undici/docs/docs/api/Errors.md +49 -0
  115. package/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  116. package/node_modules/undici/docs/docs/api/Fetch.md +60 -0
  117. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
  118. package/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
  119. package/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  120. package/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  121. package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  122. package/node_modules/undici/docs/docs/api/MockClient.md +81 -0
  123. package/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  124. package/node_modules/undici/docs/docs/api/MockPool.md +555 -0
  125. package/node_modules/undici/docs/docs/api/Pool.md +84 -0
  126. package/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  127. package/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
  128. package/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
  129. package/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
  130. package/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
  131. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
  132. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
  133. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +275 -0
  134. package/node_modules/undici/docs/docs/api/Util.md +25 -0
  135. package/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
  136. package/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  137. package/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  138. package/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
  139. package/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  140. package/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  141. package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
  142. package/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
  143. package/node_modules/undici/index-fetch.js +65 -0
  144. package/node_modules/undici/index.d.ts +3 -0
  145. package/node_modules/undici/index.js +234 -0
  146. package/node_modules/undici/lib/api/abort-signal.js +59 -0
  147. package/node_modules/undici/lib/api/api-connect.js +110 -0
  148. package/node_modules/undici/lib/api/api-pipeline.js +252 -0
  149. package/node_modules/undici/lib/api/api-request.js +214 -0
  150. package/node_modules/undici/lib/api/api-stream.js +209 -0
  151. package/node_modules/undici/lib/api/api-upgrade.js +111 -0
  152. package/node_modules/undici/lib/api/index.js +7 -0
  153. package/node_modules/undici/lib/api/readable.js +580 -0
  154. package/node_modules/undici/lib/cache/memory-cache-store.js +279 -0
  155. package/node_modules/undici/lib/cache/sqlite-cache-store.js +467 -0
  156. package/node_modules/undici/lib/core/connect.js +153 -0
  157. package/node_modules/undici/lib/core/constants.js +143 -0
  158. package/node_modules/undici/lib/core/diagnostics.js +227 -0
  159. package/node_modules/undici/lib/core/errors.js +477 -0
  160. package/node_modules/undici/lib/core/request.js +464 -0
  161. package/node_modules/undici/lib/core/socks5-client.js +422 -0
  162. package/node_modules/undici/lib/core/socks5-utils.js +212 -0
  163. package/node_modules/undici/lib/core/symbols.js +75 -0
  164. package/node_modules/undici/lib/core/tree.js +160 -0
  165. package/node_modules/undici/lib/core/util.js +992 -0
  166. package/node_modules/undici/lib/dispatcher/agent.js +158 -0
  167. package/node_modules/undici/lib/dispatcher/balanced-pool.js +221 -0
  168. package/node_modules/undici/lib/dispatcher/client-h1.js +1739 -0
  169. package/node_modules/undici/lib/dispatcher/client-h2.js +1051 -0
  170. package/node_modules/undici/lib/dispatcher/client.js +668 -0
  171. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +184 -0
  172. package/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  173. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  174. package/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  175. package/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  176. package/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  177. package/node_modules/undici/lib/dispatcher/pool.js +118 -0
  178. package/node_modules/undici/lib/dispatcher/proxy-agent.js +319 -0
  179. package/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  180. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  181. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +260 -0
  182. package/node_modules/undici/lib/encoding/index.js +33 -0
  183. package/node_modules/undici/lib/global.js +59 -0
  184. package/node_modules/undici/lib/handler/cache-handler.js +776 -0
  185. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  186. package/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  187. package/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
  188. package/node_modules/undici/lib/handler/redirect-handler.js +238 -0
  189. package/node_modules/undici/lib/handler/retry-handler.js +453 -0
  190. package/node_modules/undici/lib/handler/unwrap-handler.js +106 -0
  191. package/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  192. package/node_modules/undici/lib/interceptor/cache.js +621 -0
  193. package/node_modules/undici/lib/interceptor/decompress.js +391 -0
  194. package/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  195. package/node_modules/undici/lib/interceptor/dns.js +571 -0
  196. package/node_modules/undici/lib/interceptor/dump.js +99 -0
  197. package/node_modules/undici/lib/interceptor/redirect.js +21 -0
  198. package/node_modules/undici/lib/interceptor/response-error.js +95 -0
  199. package/node_modules/undici/lib/interceptor/retry.js +19 -0
  200. package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  201. package/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  202. package/node_modules/undici/lib/llhttp/constants.js +531 -0
  203. package/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  204. package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  205. package/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  206. package/node_modules/undici/lib/llhttp/utils.js +12 -0
  207. package/node_modules/undici/lib/mock/mock-agent.js +232 -0
  208. package/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  209. package/node_modules/undici/lib/mock/mock-client.js +68 -0
  210. package/node_modules/undici/lib/mock/mock-errors.js +29 -0
  211. package/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  212. package/node_modules/undici/lib/mock/mock-pool.js +68 -0
  213. package/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  214. package/node_modules/undici/lib/mock/mock-utils.js +486 -0
  215. package/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  216. package/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  217. package/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  218. package/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  219. package/node_modules/undici/lib/util/cache.js +676 -0
  220. package/node_modules/undici/lib/util/date.js +670 -0
  221. package/node_modules/undici/lib/util/promise.js +28 -0
  222. package/node_modules/undici/lib/util/runtime-features.js +124 -0
  223. package/node_modules/undici/lib/util/stats.js +32 -0
  224. package/node_modules/undici/lib/util/timers.js +425 -0
  225. package/node_modules/undici/lib/web/cache/cache.js +864 -0
  226. package/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  227. package/node_modules/undici/lib/web/cache/util.js +45 -0
  228. package/node_modules/undici/lib/web/cookies/constants.js +12 -0
  229. package/node_modules/undici/lib/web/cookies/index.js +199 -0
  230. package/node_modules/undici/lib/web/cookies/parse.js +314 -0
  231. package/node_modules/undici/lib/web/cookies/util.js +352 -0
  232. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +494 -0
  233. package/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
  234. package/node_modules/undici/lib/web/eventsource/util.js +29 -0
  235. package/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  236. package/node_modules/undici/lib/web/fetch/body.js +509 -0
  237. package/node_modules/undici/lib/web/fetch/constants.js +131 -0
  238. package/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  239. package/node_modules/undici/lib/web/fetch/formdata-parser.js +586 -0
  240. package/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  241. package/node_modules/undici/lib/web/fetch/global.js +40 -0
  242. package/node_modules/undici/lib/web/fetch/headers.js +719 -0
  243. package/node_modules/undici/lib/web/fetch/index.js +2413 -0
  244. package/node_modules/undici/lib/web/fetch/request.js +1115 -0
  245. package/node_modules/undici/lib/web/fetch/response.js +641 -0
  246. package/node_modules/undici/lib/web/fetch/util.js +1522 -0
  247. package/node_modules/undici/lib/web/infra/index.js +229 -0
  248. package/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  249. package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  250. package/node_modules/undici/lib/web/webidl/index.js +1006 -0
  251. package/node_modules/undici/lib/web/websocket/connection.js +329 -0
  252. package/node_modules/undici/lib/web/websocket/constants.js +126 -0
  253. package/node_modules/undici/lib/web/websocket/events.js +331 -0
  254. package/node_modules/undici/lib/web/websocket/frame.js +133 -0
  255. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +105 -0
  256. package/node_modules/undici/lib/web/websocket/receiver.js +507 -0
  257. package/node_modules/undici/lib/web/websocket/sender.js +109 -0
  258. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  259. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +496 -0
  260. package/node_modules/undici/lib/web/websocket/util.js +347 -0
  261. package/node_modules/undici/lib/web/websocket/websocket.js +758 -0
  262. package/node_modules/undici/package.json +152 -0
  263. package/node_modules/undici/scripts/strip-comments.js +10 -0
  264. package/node_modules/undici/types/README.md +6 -0
  265. package/node_modules/undici/types/agent.d.ts +32 -0
  266. package/node_modules/undici/types/api.d.ts +43 -0
  267. package/node_modules/undici/types/balanced-pool.d.ts +30 -0
  268. package/node_modules/undici/types/cache-interceptor.d.ts +179 -0
  269. package/node_modules/undici/types/cache.d.ts +36 -0
  270. package/node_modules/undici/types/client-stats.d.ts +15 -0
  271. package/node_modules/undici/types/client.d.ts +139 -0
  272. package/node_modules/undici/types/connector.d.ts +36 -0
  273. package/node_modules/undici/types/content-type.d.ts +21 -0
  274. package/node_modules/undici/types/cookies.d.ts +30 -0
  275. package/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
  276. package/node_modules/undici/types/dispatcher.d.ts +275 -0
  277. package/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  278. package/node_modules/undici/types/errors.d.ts +177 -0
  279. package/node_modules/undici/types/eventsource.d.ts +66 -0
  280. package/node_modules/undici/types/fetch.d.ts +231 -0
  281. package/node_modules/undici/types/formdata.d.ts +114 -0
  282. package/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  283. package/node_modules/undici/types/global-origin.d.ts +7 -0
  284. package/node_modules/undici/types/h2c-client.d.ts +73 -0
  285. package/node_modules/undici/types/handlers.d.ts +14 -0
  286. package/node_modules/undici/types/header.d.ts +160 -0
  287. package/node_modules/undici/types/index.d.ts +91 -0
  288. package/node_modules/undici/types/interceptors.d.ts +82 -0
  289. package/node_modules/undici/types/mock-agent.d.ts +68 -0
  290. package/node_modules/undici/types/mock-call-history.d.ts +111 -0
  291. package/node_modules/undici/types/mock-client.d.ts +27 -0
  292. package/node_modules/undici/types/mock-errors.d.ts +12 -0
  293. package/node_modules/undici/types/mock-interceptor.d.ts +94 -0
  294. package/node_modules/undici/types/mock-pool.d.ts +27 -0
  295. package/node_modules/undici/types/patch.d.ts +29 -0
  296. package/node_modules/undici/types/pool-stats.d.ts +19 -0
  297. package/node_modules/undici/types/pool.d.ts +41 -0
  298. package/node_modules/undici/types/proxy-agent.d.ts +29 -0
  299. package/node_modules/undici/types/readable.d.ts +68 -0
  300. package/node_modules/undici/types/retry-agent.d.ts +8 -0
  301. package/node_modules/undici/types/retry-handler.d.ts +125 -0
  302. package/node_modules/undici/types/round-robin-pool.d.ts +41 -0
  303. package/node_modules/undici/types/snapshot-agent.d.ts +109 -0
  304. package/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
  305. package/node_modules/undici/types/util.d.ts +18 -0
  306. package/node_modules/undici/types/utility.d.ts +7 -0
  307. package/node_modules/undici/types/webidl.d.ts +347 -0
  308. package/node_modules/undici/types/websocket.d.ts +188 -0
  309. package/package.json +3 -1
@@ -0,0 +1,1739 @@
1
+ 'use strict'
2
+
3
+ /* global WebAssembly */
4
+
5
+ const assert = require('node:assert')
6
+ const util = require('../core/util.js')
7
+ const { channels } = require('../core/diagnostics.js')
8
+ const timers = require('../util/timers.js')
9
+ const {
10
+ RequestContentLengthMismatchError,
11
+ ResponseContentLengthMismatchError,
12
+ RequestAbortedError,
13
+ InvalidArgumentError,
14
+ HeadersTimeoutError,
15
+ HeadersOverflowError,
16
+ SocketError,
17
+ InformationalError,
18
+ BodyTimeoutError,
19
+ HTTPParserError,
20
+ ResponseExceededMaxSizeError
21
+ } = require('../core/errors.js')
22
+ const {
23
+ kUrl,
24
+ kReset,
25
+ kClient,
26
+ kParser,
27
+ kBlocking,
28
+ kRunning,
29
+ kPending,
30
+ kSize,
31
+ kWriting,
32
+ kQueue,
33
+ kNoRef,
34
+ kKeepAliveDefaultTimeout,
35
+ kHostHeader,
36
+ kPendingIdx,
37
+ kRunningIdx,
38
+ kError,
39
+ kPipelining,
40
+ kSocket,
41
+ kKeepAliveTimeoutValue,
42
+ kMaxHeadersSize,
43
+ kKeepAliveMaxTimeout,
44
+ kKeepAliveTimeoutThreshold,
45
+ kHeadersTimeout,
46
+ kBodyTimeout,
47
+ kStrictContentLength,
48
+ kMaxRequests,
49
+ kCounter,
50
+ kMaxResponseSize,
51
+ kOnError,
52
+ kResume,
53
+ kHTTPContext,
54
+ kClosed
55
+ } = require('../core/symbols.js')
56
+
57
+ const constants = require('../llhttp/constants.js')
58
+ const EMPTY_BUF = Buffer.alloc(0)
59
+ const FastBuffer = Buffer[Symbol.species]
60
+ const removeAllListeners = util.removeAllListeners
61
+ const kIdleSocketValidation = Symbol('kIdleSocketValidation')
62
+ const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
63
+ const kSocketUsed = Symbol('kSocketUsed')
64
+
65
+ let extractBody
66
+
67
+ function lazyllhttp () {
68
+ const llhttpWasmData = process.env.JEST_WORKER_ID ? require('../llhttp/llhttp-wasm.js') : undefined
69
+
70
+ let mod
71
+
72
+ // We disable wasm SIMD on ppc64 as it seems to be broken on Power 9 architectures.
73
+ let useWasmSIMD = process.arch !== 'ppc64'
74
+ // The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior
75
+ if (process.env.UNDICI_NO_WASM_SIMD === '1') {
76
+ useWasmSIMD = false
77
+ } else if (process.env.UNDICI_NO_WASM_SIMD === '0') {
78
+ useWasmSIMD = true
79
+ }
80
+
81
+ if (useWasmSIMD) {
82
+ try {
83
+ mod = new WebAssembly.Module(require('../llhttp/llhttp_simd-wasm.js'))
84
+ } catch {
85
+ }
86
+ }
87
+
88
+ if (!mod) {
89
+ // We could check if the error was caused by the simd option not
90
+ // being enabled, but the occurring of this other error
91
+ // * https://github.com/emscripten-core/emscripten/issues/11495
92
+ // got me to remove that check to avoid breaking Node 12.
93
+ mod = new WebAssembly.Module(llhttpWasmData || require('../llhttp/llhttp-wasm.js'))
94
+ }
95
+
96
+ return new WebAssembly.Instance(mod, {
97
+ env: {
98
+ /**
99
+ * @param {number} p
100
+ * @param {number} at
101
+ * @param {number} len
102
+ * @returns {number}
103
+ */
104
+ wasm_on_url: (p, at, len) => {
105
+ return 0
106
+ },
107
+ /**
108
+ * @param {number} p
109
+ * @param {number} at
110
+ * @param {number} len
111
+ * @returns {number}
112
+ */
113
+ wasm_on_status: (p, at, len) => {
114
+ assert(currentParser.ptr === p)
115
+ const start = at - currentBufferPtr + currentBufferRef.byteOffset
116
+ return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len))
117
+ },
118
+ /**
119
+ * @param {number} p
120
+ * @returns {number}
121
+ */
122
+ wasm_on_message_begin: (p) => {
123
+ assert(currentParser.ptr === p)
124
+ return currentParser.onMessageBegin()
125
+ },
126
+ /**
127
+ * @param {number} p
128
+ * @param {number} at
129
+ * @param {number} len
130
+ * @returns {number}
131
+ */
132
+ wasm_on_header_field: (p, at, len) => {
133
+ assert(currentParser.ptr === p)
134
+ const start = at - currentBufferPtr + currentBufferRef.byteOffset
135
+ return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len))
136
+ },
137
+ /**
138
+ * @param {number} p
139
+ * @param {number} at
140
+ * @param {number} len
141
+ * @returns {number}
142
+ */
143
+ wasm_on_header_value: (p, at, len) => {
144
+ assert(currentParser.ptr === p)
145
+ const start = at - currentBufferPtr + currentBufferRef.byteOffset
146
+ return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len))
147
+ },
148
+ /**
149
+ * @param {number} p
150
+ * @param {number} statusCode
151
+ * @param {0|1} upgrade
152
+ * @param {0|1} shouldKeepAlive
153
+ * @returns {number}
154
+ */
155
+ wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
156
+ assert(currentParser.ptr === p)
157
+ return currentParser.onHeadersComplete(statusCode, upgrade === 1, shouldKeepAlive === 1)
158
+ },
159
+ /**
160
+ * @param {number} p
161
+ * @param {number} at
162
+ * @param {number} len
163
+ * @returns {number}
164
+ */
165
+ wasm_on_body: (p, at, len) => {
166
+ assert(currentParser.ptr === p)
167
+ const start = at - currentBufferPtr + currentBufferRef.byteOffset
168
+ return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len))
169
+ },
170
+ /**
171
+ * @param {number} p
172
+ * @returns {number}
173
+ */
174
+ wasm_on_message_complete: (p) => {
175
+ assert(currentParser.ptr === p)
176
+ return currentParser.onMessageComplete()
177
+ }
178
+
179
+ }
180
+ })
181
+ }
182
+
183
+ let llhttpInstance = null
184
+
185
+ /**
186
+ * @type {Parser|null}
187
+ */
188
+ let currentParser = null
189
+ let currentBufferRef = null
190
+ /**
191
+ * @type {number}
192
+ */
193
+ let currentBufferSize = 0
194
+ let currentBufferPtr = null
195
+
196
+ const USE_NATIVE_TIMER = 0
197
+ const USE_FAST_TIMER = 1
198
+
199
+ // Use fast timers for headers and body to take eventual event loop
200
+ // latency into account.
201
+ const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER
202
+ const TIMEOUT_BODY = 4 | USE_FAST_TIMER
203
+
204
+ // Use native timers to ignore event loop latency for keep-alive
205
+ // handling.
206
+ const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER
207
+
208
+ class Parser {
209
+ /**
210
+ * @param {import('./client.js')} client
211
+ * @param {import('net').Socket} socket
212
+ * @param {*} llhttp
213
+ */
214
+ constructor (client, socket, { exports }) {
215
+ this.llhttp = exports
216
+ this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE)
217
+ this.client = client
218
+ /**
219
+ * @type {import('net').Socket}
220
+ */
221
+ this.socket = socket
222
+ this.timeout = null
223
+ this.timeoutWeakRef = new WeakRef(this)
224
+ this.timeoutValue = null
225
+ this.timeoutType = null
226
+ this.statusCode = 0
227
+ this.statusText = ''
228
+ this.upgrade = false
229
+ this.headers = []
230
+ this.headersSize = 0
231
+ this.headersMaxSize = client[kMaxHeadersSize]
232
+ this.shouldKeepAlive = false
233
+ this.paused = false
234
+ this.resume = this.resume.bind(this)
235
+
236
+ this.bytesRead = 0
237
+
238
+ this.keepAlive = ''
239
+ this.contentLength = ''
240
+ this.connection = ''
241
+ this.maxResponseSize = client[kMaxResponseSize]
242
+ }
243
+
244
+ setTimeout (delay, type) {
245
+ // If the existing timer and the new timer are of different timer type
246
+ // (fast or native) or have different delay, we need to clear the existing
247
+ // timer and set a new one.
248
+ if (
249
+ delay !== this.timeoutValue ||
250
+ (type & USE_FAST_TIMER) ^ (this.timeoutType & USE_FAST_TIMER)
251
+ ) {
252
+ // If a timeout is already set, clear it with clearTimeout of the fast
253
+ // timer implementation, as it can clear fast and native timers.
254
+ if (this.timeout) {
255
+ timers.clearTimeout(this.timeout)
256
+ this.timeout = null
257
+ }
258
+
259
+ if (delay) {
260
+ if (type & USE_FAST_TIMER) {
261
+ this.timeout = timers.setFastTimeout(onParserTimeout, delay, this.timeoutWeakRef)
262
+ } else {
263
+ this.timeout = setTimeout(onParserTimeout, delay, this.timeoutWeakRef)
264
+ this.timeout?.unref()
265
+ }
266
+ }
267
+
268
+ this.timeoutValue = delay
269
+ } else if (this.timeout) {
270
+ if (this.timeout.refresh) {
271
+ this.timeout.refresh()
272
+ }
273
+ }
274
+
275
+ this.timeoutType = type
276
+ }
277
+
278
+ resume () {
279
+ if (this.socket.destroyed || !this.paused) {
280
+ return
281
+ }
282
+
283
+ assert(this.ptr != null)
284
+ assert(currentParser === null)
285
+
286
+ this.llhttp.llhttp_resume(this.ptr)
287
+
288
+ assert(this.timeoutType === TIMEOUT_BODY)
289
+ if (this.timeout) {
290
+ if (this.timeout.refresh) {
291
+ this.timeout.refresh()
292
+ }
293
+ }
294
+
295
+ this.paused = false
296
+ this.execute(this.socket.read() || EMPTY_BUF) // Flush parser.
297
+ this.readMore()
298
+ }
299
+
300
+ readMore () {
301
+ while (!this.paused && this.ptr) {
302
+ const chunk = this.socket.read()
303
+ if (chunk === null) {
304
+ break
305
+ }
306
+ this.execute(chunk)
307
+ }
308
+ }
309
+
310
+ /**
311
+ * @param {Buffer} chunk
312
+ */
313
+ execute (chunk) {
314
+ assert(currentParser === null)
315
+ assert(this.ptr != null)
316
+ assert(!this.paused)
317
+
318
+ const { socket, llhttp } = this
319
+
320
+ // Allocate a new buffer if the current buffer is too small.
321
+ if (chunk.length > currentBufferSize) {
322
+ if (currentBufferPtr) {
323
+ llhttp.free(currentBufferPtr)
324
+ }
325
+ // Allocate a buffer that is a multiple of 4096 bytes.
326
+ currentBufferSize = Math.ceil(chunk.length / 4096) * 4096
327
+ currentBufferPtr = llhttp.malloc(currentBufferSize)
328
+ }
329
+
330
+ new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(chunk)
331
+
332
+ // Call `execute` on the wasm parser.
333
+ // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
334
+ // and finally the length of bytes to parse.
335
+ // The return value is an error code or `constants.ERROR.OK`.
336
+ try {
337
+ let ret
338
+
339
+ try {
340
+ currentBufferRef = chunk
341
+ currentParser = this
342
+ ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, chunk.length)
343
+ } finally {
344
+ currentParser = null
345
+ currentBufferRef = null
346
+ }
347
+
348
+ if (ret !== constants.ERROR.OK) {
349
+ const data = chunk.subarray(llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr)
350
+
351
+ if (ret === constants.ERROR.PAUSED_UPGRADE) {
352
+ this.onUpgrade(data)
353
+ } else if (ret === constants.ERROR.PAUSED) {
354
+ this.paused = true
355
+ socket.unshift(data)
356
+ } else {
357
+ throw this.createError(ret, data)
358
+ }
359
+ }
360
+ } catch (err) {
361
+ util.destroy(socket, err)
362
+ }
363
+ }
364
+
365
+ finish () {
366
+ assert(currentParser === null)
367
+ assert(this.ptr != null)
368
+ assert(!this.paused)
369
+
370
+ const { llhttp } = this
371
+
372
+ let ret
373
+
374
+ try {
375
+ currentParser = this
376
+ ret = llhttp.llhttp_finish(this.ptr)
377
+ } finally {
378
+ currentParser = null
379
+ }
380
+
381
+ if (ret === constants.ERROR.OK) {
382
+ return null
383
+ }
384
+
385
+ if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
386
+ this.paused = true
387
+ return null
388
+ }
389
+
390
+ return this.createError(ret, EMPTY_BUF)
391
+ }
392
+
393
+ createError (ret, data) {
394
+ const { llhttp, contentLength, bytesRead } = this
395
+
396
+ if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
397
+ return new ResponseContentLengthMismatchError()
398
+ }
399
+
400
+ const ptr = llhttp.llhttp_get_error_reason(this.ptr)
401
+ let message = ''
402
+ if (ptr) {
403
+ const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
404
+ message =
405
+ 'Response does not match the HTTP/1.1 protocol (' +
406
+ Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
407
+ ')'
408
+ }
409
+
410
+ return new HTTPParserError(message, constants.ERROR[ret], data)
411
+ }
412
+
413
+ destroy () {
414
+ assert(currentParser === null)
415
+ assert(this.ptr != null)
416
+
417
+ this.llhttp.llhttp_free(this.ptr)
418
+ this.ptr = null
419
+
420
+ this.timeout && timers.clearTimeout(this.timeout)
421
+ this.timeout = null
422
+ this.timeoutValue = null
423
+ this.timeoutType = null
424
+
425
+ this.paused = false
426
+ }
427
+
428
+ /**
429
+ * @param {Buffer} buf
430
+ * @returns {0}
431
+ */
432
+ onStatus (buf) {
433
+ this.statusText = buf.toString()
434
+ return 0
435
+ }
436
+
437
+ /**
438
+ * @returns {0|-1}
439
+ */
440
+ onMessageBegin () {
441
+ const { socket, client } = this
442
+
443
+ if (socket.destroyed) {
444
+ return -1
445
+ }
446
+
447
+ if (client[kRunning] === 0) {
448
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
449
+ return -1
450
+ }
451
+
452
+ const request = client[kQueue][client[kRunningIdx]]
453
+ if (!request) {
454
+ return -1
455
+ }
456
+ request.onResponseStarted()
457
+
458
+ return 0
459
+ }
460
+
461
+ /**
462
+ * @param {Buffer} buf
463
+ * @returns {number}
464
+ */
465
+ onHeaderField (buf) {
466
+ const len = this.headers.length
467
+
468
+ if ((len & 1) === 0) {
469
+ this.headers.push(buf)
470
+ } else {
471
+ this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
472
+ }
473
+
474
+ this.trackHeader(buf.length)
475
+
476
+ return 0
477
+ }
478
+
479
+ /**
480
+ * @param {Buffer} buf
481
+ * @returns {number}
482
+ */
483
+ onHeaderValue (buf) {
484
+ let len = this.headers.length
485
+
486
+ if ((len & 1) === 1) {
487
+ this.headers.push(buf)
488
+ len += 1
489
+ } else {
490
+ this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
491
+ }
492
+
493
+ const key = this.headers[len - 2]
494
+ if (key.length === 10) {
495
+ const headerName = util.bufferToLowerCasedHeaderName(key)
496
+ if (headerName === 'keep-alive') {
497
+ this.keepAlive += buf.toString()
498
+ } else if (headerName === 'connection') {
499
+ this.connection += buf.toString()
500
+ }
501
+ } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') {
502
+ this.contentLength += buf.toString()
503
+ }
504
+
505
+ this.trackHeader(buf.length)
506
+
507
+ return 0
508
+ }
509
+
510
+ /**
511
+ * @param {number} len
512
+ */
513
+ trackHeader (len) {
514
+ this.headersSize += len
515
+ if (this.headersSize >= this.headersMaxSize) {
516
+ util.destroy(this.socket, new HeadersOverflowError())
517
+ }
518
+ }
519
+
520
+ /**
521
+ * @param {Buffer} head
522
+ */
523
+ onUpgrade (head) {
524
+ const { upgrade, client, socket, headers, statusCode } = this
525
+
526
+ assert(upgrade)
527
+ assert(client[kSocket] === socket)
528
+ assert(!socket.destroyed)
529
+ assert(!this.paused)
530
+ assert((headers.length & 1) === 0)
531
+
532
+ const request = client[kQueue][client[kRunningIdx]]
533
+ assert(request)
534
+ assert(request.upgrade || request.method === 'CONNECT')
535
+
536
+ this.statusCode = 0
537
+ this.statusText = ''
538
+ this.shouldKeepAlive = false
539
+
540
+ this.headers = []
541
+ this.headersSize = 0
542
+
543
+ socket.unshift(head)
544
+
545
+ socket[kParser].destroy()
546
+ socket[kParser] = null
547
+
548
+ socket[kClient] = null
549
+ socket[kError] = null
550
+
551
+ removeAllListeners(socket)
552
+
553
+ client[kSocket] = null
554
+ client[kHTTPContext] = null // TODO (fix): This is hacky...
555
+ client[kQueue][client[kRunningIdx]++] = null
556
+ client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade'))
557
+
558
+ try {
559
+ request.onUpgrade(statusCode, headers, socket)
560
+ } catch (err) {
561
+ util.destroy(socket, err)
562
+ }
563
+
564
+ client[kResume]()
565
+ }
566
+
567
+ /**
568
+ * @param {number} statusCode
569
+ * @param {boolean} upgrade
570
+ * @param {boolean} shouldKeepAlive
571
+ * @returns {number}
572
+ */
573
+ onHeadersComplete (statusCode, upgrade, shouldKeepAlive) {
574
+ const { client, socket, headers, statusText } = this
575
+
576
+ if (socket.destroyed) {
577
+ return -1
578
+ }
579
+
580
+ if (client[kRunning] === 0) {
581
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
582
+ return -1
583
+ }
584
+
585
+ const request = client[kQueue][client[kRunningIdx]]
586
+
587
+ if (!request) {
588
+ return -1
589
+ }
590
+
591
+ assert(!this.upgrade)
592
+ assert(this.statusCode < 200)
593
+
594
+ if (statusCode === 100) {
595
+ util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
596
+ return -1
597
+ }
598
+
599
+ /* this can only happen if server is misbehaving */
600
+ if (upgrade && !request.upgrade) {
601
+ util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket)))
602
+ return -1
603
+ }
604
+
605
+ assert(this.timeoutType === TIMEOUT_HEADERS)
606
+
607
+ this.statusCode = statusCode
608
+ this.shouldKeepAlive = (
609
+ shouldKeepAlive ||
610
+ // Override llhttp value which does not allow keepAlive for HEAD.
611
+ (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive')
612
+ )
613
+
614
+ if (this.statusCode >= 200) {
615
+ const bodyTimeout = request.bodyTimeout != null
616
+ ? request.bodyTimeout
617
+ : client[kBodyTimeout]
618
+ this.setTimeout(bodyTimeout, TIMEOUT_BODY)
619
+ } else if (this.timeout) {
620
+ if (this.timeout.refresh) {
621
+ this.timeout.refresh()
622
+ }
623
+ }
624
+
625
+ if (request.method === 'CONNECT') {
626
+ assert(client[kRunning] === 1)
627
+ this.upgrade = true
628
+ return 2
629
+ }
630
+
631
+ if (upgrade) {
632
+ assert(client[kRunning] === 1)
633
+ this.upgrade = true
634
+ return 2
635
+ }
636
+
637
+ assert((this.headers.length & 1) === 0)
638
+ this.headers = []
639
+ this.headersSize = 0
640
+
641
+ if (this.shouldKeepAlive && client[kPipelining]) {
642
+ const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null
643
+
644
+ if (keepAliveTimeout != null) {
645
+ const timeout = Math.min(
646
+ keepAliveTimeout - client[kKeepAliveTimeoutThreshold],
647
+ client[kKeepAliveMaxTimeout]
648
+ )
649
+ if (timeout <= 0) {
650
+ socket[kReset] = true
651
+ } else {
652
+ client[kKeepAliveTimeoutValue] = timeout
653
+ }
654
+ } else {
655
+ client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]
656
+ }
657
+ } else {
658
+ // Stop more requests from being dispatched.
659
+ socket[kReset] = true
660
+ }
661
+
662
+ const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false
663
+
664
+ if (request.aborted) {
665
+ return -1
666
+ }
667
+
668
+ if (request.method === 'HEAD') {
669
+ return 1
670
+ }
671
+
672
+ if (statusCode < 200) {
673
+ return 1
674
+ }
675
+
676
+ if (socket[kBlocking]) {
677
+ socket[kBlocking] = false
678
+ client[kResume]()
679
+ }
680
+
681
+ return pause ? constants.ERROR.PAUSED : 0
682
+ }
683
+
684
+ /**
685
+ * @param {Buffer} buf
686
+ * @returns {number}
687
+ */
688
+ onBody (buf) {
689
+ const { client, socket, statusCode, maxResponseSize } = this
690
+
691
+ if (socket.destroyed) {
692
+ return -1
693
+ }
694
+
695
+ const request = client[kQueue][client[kRunningIdx]]
696
+ assert(request)
697
+
698
+ assert(this.timeoutType === TIMEOUT_BODY)
699
+ if (this.timeout) {
700
+ if (this.timeout.refresh) {
701
+ this.timeout.refresh()
702
+ }
703
+ }
704
+
705
+ assert(statusCode >= 200)
706
+
707
+ if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) {
708
+ util.destroy(socket, new ResponseExceededMaxSizeError())
709
+ return -1
710
+ }
711
+
712
+ this.bytesRead += buf.length
713
+
714
+ if (request.onData(buf) === false) {
715
+ return constants.ERROR.PAUSED
716
+ }
717
+
718
+ return 0
719
+ }
720
+
721
+ /**
722
+ * @returns {number}
723
+ */
724
+ onMessageComplete () {
725
+ const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this
726
+
727
+ if (socket.destroyed && (!statusCode || shouldKeepAlive)) {
728
+ return -1
729
+ }
730
+
731
+ if (upgrade) {
732
+ return 0
733
+ }
734
+
735
+ assert(statusCode >= 100)
736
+ assert((this.headers.length & 1) === 0)
737
+
738
+ const request = client[kQueue][client[kRunningIdx]]
739
+ assert(request)
740
+
741
+ this.statusCode = 0
742
+ this.statusText = ''
743
+ this.bytesRead = 0
744
+ this.contentLength = ''
745
+ this.keepAlive = ''
746
+ this.connection = ''
747
+
748
+ this.headers = []
749
+ this.headersSize = 0
750
+
751
+ if (statusCode < 200) {
752
+ return 0
753
+ }
754
+
755
+ if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) {
756
+ util.destroy(socket, new ResponseContentLengthMismatchError())
757
+ return -1
758
+ }
759
+
760
+ request.onComplete(headers)
761
+
762
+ client[kQueue][client[kRunningIdx]++] = null
763
+ socket[kSocketUsed] = client[kPending] === 0
764
+
765
+ if (socket[kWriting]) {
766
+ assert(client[kRunning] === 0)
767
+ // Response completed before request.
768
+ util.destroy(socket, new InformationalError('reset'))
769
+ return constants.ERROR.PAUSED
770
+ } else if (!shouldKeepAlive) {
771
+ util.destroy(socket, new InformationalError('reset'))
772
+ return constants.ERROR.PAUSED
773
+ } else if (socket[kReset] && client[kRunning] === 0) {
774
+ // Destroy socket once all requests have completed.
775
+ // The request at the tail of the pipeline is the one
776
+ // that requested reset and no further requests should
777
+ // have been queued since then.
778
+ util.destroy(socket, new InformationalError('reset'))
779
+ return constants.ERROR.PAUSED
780
+ } else if (client[kPipelining] == null || client[kPipelining] === 1) {
781
+ // We must wait a full event loop cycle to reuse this socket to make sure
782
+ // that non-spec compliant servers are not closing the connection even if they
783
+ // said they won't.
784
+ setImmediate(client[kResume])
785
+ } else {
786
+ client[kResume]()
787
+ }
788
+
789
+ return 0
790
+ }
791
+ }
792
+
793
+ function onParserTimeout (parserWeakRef) {
794
+ const parser = parserWeakRef.deref()
795
+ if (!parser) {
796
+ return
797
+ }
798
+
799
+ const { socket, timeoutType, client, paused } = parser
800
+
801
+ if (timeoutType === TIMEOUT_HEADERS) {
802
+ if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) {
803
+ assert(!paused, 'cannot be paused while waiting for headers')
804
+ util.destroy(socket, new HeadersTimeoutError())
805
+ }
806
+ } else if (timeoutType === TIMEOUT_BODY) {
807
+ if (!paused) {
808
+ util.destroy(socket, new BodyTimeoutError())
809
+ }
810
+ } else if (timeoutType === TIMEOUT_KEEP_ALIVE) {
811
+ assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue])
812
+ util.destroy(socket, new InformationalError('socket idle timeout'))
813
+ }
814
+ }
815
+
816
+ /**
817
+ * @param {import ('./client.js')} client
818
+ * @param {import('net').Socket} socket
819
+ * @returns
820
+ */
821
+ function connectH1 (client, socket) {
822
+ client[kSocket] = socket
823
+
824
+ if (!llhttpInstance) {
825
+ llhttpInstance = lazyllhttp()
826
+ }
827
+
828
+ if (socket.errored) {
829
+ throw socket.errored
830
+ }
831
+
832
+ if (socket.destroyed) {
833
+ throw new SocketError('destroyed')
834
+ }
835
+
836
+ socket[kNoRef] = false
837
+ socket[kWriting] = false
838
+ socket[kReset] = false
839
+ socket[kBlocking] = false
840
+ socket[kIdleSocketValidation] = 0
841
+ socket[kIdleSocketValidationTimeout] = null
842
+ socket[kSocketUsed] = false
843
+ socket[kParser] = new Parser(client, socket, llhttpInstance)
844
+
845
+ util.addListener(socket, 'error', onHttpSocketError)
846
+ util.addListener(socket, 'readable', onHttpSocketReadable)
847
+ util.addListener(socket, 'end', onHttpSocketEnd)
848
+ util.addListener(socket, 'close', onHttpSocketClose)
849
+
850
+ socket[kClosed] = false
851
+ socket.on('close', onSocketClose)
852
+
853
+ return {
854
+ version: 'h1',
855
+ defaultPipelining: 1,
856
+ write (request) {
857
+ return writeH1(client, request)
858
+ },
859
+ resume () {
860
+ resumeH1(client)
861
+ },
862
+ /**
863
+ * @param {Error|undefined} err
864
+ * @param {() => void} callback
865
+ */
866
+ destroy (err, callback) {
867
+ if (socket[kClosed]) {
868
+ queueMicrotask(callback)
869
+ } else {
870
+ socket.on('close', callback)
871
+ socket.destroy(err)
872
+ }
873
+ },
874
+ /**
875
+ * @returns {boolean}
876
+ */
877
+ get destroyed () {
878
+ return socket.destroyed
879
+ },
880
+ /**
881
+ * @param {import('../core/request.js')} request
882
+ * @returns {boolean}
883
+ */
884
+ busy (request) {
885
+ if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
886
+ return true
887
+ }
888
+
889
+ if (request) {
890
+ if (client[kRunning] > 0 && !request.idempotent) {
891
+ // Non-idempotent request cannot be retried.
892
+ // Ensure that no other requests are inflight and
893
+ // could cause failure.
894
+ return true
895
+ }
896
+
897
+ if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) {
898
+ // Don't dispatch an upgrade until all preceding requests have completed.
899
+ // A misbehaving server might upgrade the connection before all pipelined
900
+ // request has completed.
901
+ return true
902
+ }
903
+
904
+ if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 &&
905
+ (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) {
906
+ // Request with stream or iterator body can error while other requests
907
+ // are inflight and indirectly error those as well.
908
+ // Ensure this doesn't happen by waiting for inflight
909
+ // to complete before dispatching.
910
+
911
+ // Request with stream or iterator body cannot be retried.
912
+ // Ensure that no other requests are inflight and
913
+ // could cause failure.
914
+ return true
915
+ }
916
+ }
917
+
918
+ return false
919
+ }
920
+ }
921
+ }
922
+
923
+ function onHttpSocketError (err) {
924
+ assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
925
+
926
+ const parser = this[kParser]
927
+
928
+ // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
929
+ // to the user.
930
+ if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
931
+ const parserErr = parser.finish()
932
+ if (parserErr) {
933
+ this[kError] = parserErr
934
+ this[kClient][kOnError](parserErr)
935
+ }
936
+ return
937
+ }
938
+
939
+ this[kError] = err
940
+
941
+ this[kClient][kOnError](err)
942
+ }
943
+
944
+ function onHttpSocketReadable () {
945
+ this[kParser]?.readMore()
946
+ }
947
+
948
+ function onHttpSocketEnd () {
949
+ const parser = this[kParser]
950
+
951
+ if (parser.statusCode && !parser.shouldKeepAlive) {
952
+ const parserErr = parser.finish()
953
+ if (parserErr) {
954
+ util.destroy(this, parserErr)
955
+ }
956
+ return
957
+ }
958
+
959
+ util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this)))
960
+ }
961
+
962
+ function onHttpSocketClose () {
963
+ const parser = this[kParser]
964
+
965
+ clearIdleSocketValidation(this)
966
+
967
+ if (parser) {
968
+ if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
969
+ this[kError] = parser.finish() || this[kError]
970
+ }
971
+
972
+ this[kParser].destroy()
973
+ this[kParser] = null
974
+ }
975
+
976
+ const err = this[kError] || new SocketError('closed', util.getSocketInfo(this))
977
+
978
+ const client = this[kClient]
979
+
980
+ client[kSocket] = null
981
+ client[kHTTPContext] = null // TODO (fix): This is hacky...
982
+
983
+ if (client.destroyed) {
984
+ assert(client[kPending] === 0)
985
+
986
+ // Fail entire queue.
987
+ const requests = client[kQueue].splice(client[kRunningIdx])
988
+ for (let i = 0; i < requests.length; i++) {
989
+ const request = requests[i]
990
+ util.errorRequest(client, request, err)
991
+ }
992
+ } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') {
993
+ // Fail head of pipeline.
994
+ const request = client[kQueue][client[kRunningIdx]]
995
+ client[kQueue][client[kRunningIdx]++] = null
996
+
997
+ util.errorRequest(client, request, err)
998
+ }
999
+
1000
+ client[kPendingIdx] = client[kRunningIdx]
1001
+
1002
+ assert(client[kRunning] === 0)
1003
+
1004
+ client.emit('disconnect', client[kUrl], [client], err)
1005
+
1006
+ client[kResume]()
1007
+ }
1008
+
1009
+ function onSocketClose () {
1010
+ this[kClosed] = true
1011
+ }
1012
+
1013
+ function clearIdleSocketValidation (socket) {
1014
+ if (socket[kIdleSocketValidationTimeout]) {
1015
+ clearImmediate(socket[kIdleSocketValidationTimeout])
1016
+ socket[kIdleSocketValidationTimeout] = null
1017
+ }
1018
+
1019
+ socket[kIdleSocketValidation] = 0
1020
+ }
1021
+
1022
+ function scheduleIdleSocketValidation (client, socket) {
1023
+ socket[kIdleSocketValidation] = 1
1024
+ // Yield to the check phase (after poll) so unsolicited bytes / FIN / RST
1025
+ // already pending on this idle keep-alive socket are processed before the
1026
+ // next request is written (GHSA-35p6-xmwp-9g52).
1027
+ //
1028
+ // setTimeout(0) pays Node's ~1ms timer floor on every sequential reuse
1029
+ // (#5493). setImmediate avoids that, but an *unref'd* Immediate lets poll
1030
+ // block for ~500ms when the event loop is otherwise idle (#5600 / #5606).
1031
+ // A ref'd Immediate both keeps the pending request alive and makes poll
1032
+ // return immediately — the hybrid those issues asked for.
1033
+ socket[kIdleSocketValidationTimeout] = setImmediate(() => {
1034
+ socket[kIdleSocketValidationTimeout] = null
1035
+ socket[kIdleSocketValidation] = 2
1036
+
1037
+ if (client[kSocket] === socket && !socket.destroyed) {
1038
+ client[kResume]()
1039
+ }
1040
+ })
1041
+ }
1042
+
1043
+ /**
1044
+ * @param {import('./client.js')} client
1045
+ */
1046
+ function resumeH1 (client) {
1047
+ const socket = client[kSocket]
1048
+
1049
+ if (socket && !socket.destroyed) {
1050
+ if (client[kSize] === 0) {
1051
+ if (!socket[kNoRef] && socket.unref) {
1052
+ socket.unref()
1053
+ socket[kNoRef] = true
1054
+ }
1055
+ } else if (socket[kNoRef] && socket.ref) {
1056
+ socket.ref()
1057
+ socket[kNoRef] = false
1058
+ }
1059
+
1060
+ if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
1061
+ if (socket[kIdleSocketValidation] === 0) {
1062
+ scheduleIdleSocketValidation(client, socket)
1063
+ socket[kParser].readMore()
1064
+ if (socket.destroyed) {
1065
+ return
1066
+ }
1067
+ return
1068
+ }
1069
+
1070
+ if (socket[kIdleSocketValidation] === 1) {
1071
+ socket[kParser].readMore()
1072
+ if (socket.destroyed) {
1073
+ return
1074
+ }
1075
+ return
1076
+ }
1077
+ }
1078
+
1079
+ if (client[kRunning] === 0) {
1080
+ socket[kParser].readMore()
1081
+ if (socket.destroyed) {
1082
+ return
1083
+ }
1084
+ }
1085
+
1086
+ if (client[kSize] === 0) {
1087
+ if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
1088
+ socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
1089
+ }
1090
+ } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) {
1091
+ if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) {
1092
+ const request = client[kQueue][client[kRunningIdx]]
1093
+ const headersTimeout = request.headersTimeout != null
1094
+ ? request.headersTimeout
1095
+ : client[kHeadersTimeout]
1096
+ socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS)
1097
+ }
1098
+ }
1099
+ }
1100
+ }
1101
+
1102
+ // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2
1103
+ function shouldSendContentLength (method) {
1104
+ return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT'
1105
+ }
1106
+
1107
+ /**
1108
+ * @param {import('./client.js')} client
1109
+ * @param {import('../core/request.js')} request
1110
+ * @returns
1111
+ */
1112
+ function writeH1 (client, request) {
1113
+ const { method, path, host, upgrade, blocking, reset } = request
1114
+
1115
+ let { body, headers, contentLength } = request
1116
+
1117
+ // https://tools.ietf.org/html/rfc7231#section-4.3.1
1118
+ // https://tools.ietf.org/html/rfc7231#section-4.3.2
1119
+ // https://tools.ietf.org/html/rfc7231#section-4.3.5
1120
+
1121
+ // Sending a payload body on a request that does not
1122
+ // expect it can cause undefined behavior on some
1123
+ // servers and corrupt connection state. Do not
1124
+ // re-use the connection for further requests.
1125
+
1126
+ const expectsPayload = (
1127
+ method === 'PUT' ||
1128
+ method === 'POST' ||
1129
+ method === 'PATCH' ||
1130
+ method === 'QUERY' ||
1131
+ method === 'PROPFIND' ||
1132
+ method === 'PROPPATCH'
1133
+ )
1134
+
1135
+ if (util.isFormDataLike(body)) {
1136
+ if (!extractBody) {
1137
+ extractBody = require('../web/fetch/body.js').extractBody
1138
+ }
1139
+
1140
+ const [bodyStream, contentType] = extractBody(body)
1141
+ if (request.contentType == null) {
1142
+ headers.push('content-type', contentType)
1143
+ }
1144
+ body = bodyStream.stream
1145
+ contentLength = bodyStream.length
1146
+ } else if (util.isBlobLike(body) && request.contentType == null) {
1147
+ const contentType = body.type
1148
+ if (contentType) {
1149
+ const contentTypeValue = `${contentType}`
1150
+ if (!util.isValidHeaderValue(contentTypeValue)) {
1151
+ util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'))
1152
+ return false
1153
+ }
1154
+ headers.push('content-type', contentTypeValue)
1155
+ }
1156
+ }
1157
+
1158
+ if (body && typeof body.read === 'function') {
1159
+ // Try to read EOF in order to get length.
1160
+ body.read(0)
1161
+ }
1162
+
1163
+ const bodyLength = util.bodyLength(body)
1164
+
1165
+ contentLength = bodyLength ?? contentLength
1166
+
1167
+ if (contentLength === null) {
1168
+ contentLength = request.contentLength
1169
+ }
1170
+
1171
+ if (contentLength === 0 && !expectsPayload) {
1172
+ // https://tools.ietf.org/html/rfc7230#section-3.3.2
1173
+ // A user agent SHOULD NOT send a Content-Length header field when
1174
+ // the request message does not contain a payload body and the method
1175
+ // semantics do not anticipate such a body.
1176
+
1177
+ contentLength = null
1178
+ }
1179
+
1180
+ // https://github.com/nodejs/undici/issues/2046
1181
+ // A user agent may send a Content-Length header with 0 value, this should be allowed.
1182
+ if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) {
1183
+ if (client[kStrictContentLength]) {
1184
+ util.errorRequest(client, request, new RequestContentLengthMismatchError())
1185
+ return false
1186
+ }
1187
+
1188
+ process.emitWarning(new RequestContentLengthMismatchError())
1189
+ }
1190
+
1191
+ const socket = client[kSocket]
1192
+ clearIdleSocketValidation(socket)
1193
+
1194
+ /**
1195
+ * @param {Error} [err]
1196
+ * @returns {void}
1197
+ */
1198
+ const abort = (err) => {
1199
+ if (request.aborted || request.completed) {
1200
+ return
1201
+ }
1202
+
1203
+ util.errorRequest(client, request, err || new RequestAbortedError())
1204
+
1205
+ util.destroy(body)
1206
+ util.destroy(socket, new InformationalError('aborted'))
1207
+ }
1208
+
1209
+ try {
1210
+ request.onConnect(abort)
1211
+ } catch (err) {
1212
+ util.errorRequest(client, request, err)
1213
+ }
1214
+
1215
+ if (request.aborted) {
1216
+ return false
1217
+ }
1218
+
1219
+ if (method === 'HEAD') {
1220
+ // https://github.com/mcollina/undici/issues/258
1221
+ // Close after a HEAD request to interop with misbehaving servers
1222
+ // that may send a body in the response.
1223
+
1224
+ socket[kReset] = true
1225
+ }
1226
+
1227
+ if (upgrade || method === 'CONNECT') {
1228
+ // On CONNECT or upgrade, block pipeline from dispatching further
1229
+ // requests on this connection.
1230
+
1231
+ socket[kReset] = true
1232
+ }
1233
+
1234
+ if (reset != null) {
1235
+ socket[kReset] = reset
1236
+ }
1237
+
1238
+ if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) {
1239
+ socket[kReset] = true
1240
+ }
1241
+
1242
+ if (blocking) {
1243
+ socket[kBlocking] = true
1244
+ }
1245
+
1246
+ if (socket.setTypeOfService) {
1247
+ socket.setTypeOfService(request.typeOfService)
1248
+ }
1249
+
1250
+ let header = `${method} ${path} HTTP/1.1\r\n`
1251
+
1252
+ if (typeof host === 'string') {
1253
+ header += `host: ${host}\r\n`
1254
+ } else {
1255
+ header += client[kHostHeader]
1256
+ }
1257
+
1258
+ if (upgrade) {
1259
+ header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n`
1260
+ } else if (client[kPipelining] && !socket[kReset]) {
1261
+ header += 'connection: keep-alive\r\n'
1262
+ } else {
1263
+ header += 'connection: close\r\n'
1264
+ }
1265
+
1266
+ if (Array.isArray(headers)) {
1267
+ for (let n = 0; n < headers.length; n += 2) {
1268
+ const key = headers[n + 0]
1269
+ const val = headers[n + 1]
1270
+
1271
+ if (Array.isArray(val)) {
1272
+ for (let i = 0; i < val.length; i++) {
1273
+ header += `${key}: ${val[i]}\r\n`
1274
+ }
1275
+ } else {
1276
+ header += `${key}: ${val}\r\n`
1277
+ }
1278
+ }
1279
+ }
1280
+
1281
+ if (channels.sendHeaders.hasSubscribers) {
1282
+ channels.sendHeaders.publish({ request, headers: header, socket })
1283
+ }
1284
+
1285
+ if (!body || bodyLength === 0) {
1286
+ writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload)
1287
+ } else if (util.isBuffer(body)) {
1288
+ writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload)
1289
+ } else if (util.isBlobLike(body)) {
1290
+ if (typeof body.stream === 'function') {
1291
+ writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload)
1292
+ } else {
1293
+ writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload)
1294
+ }
1295
+ } else if (util.isStream(body)) {
1296
+ writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload)
1297
+ } else if (util.isIterable(body)) {
1298
+ writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload)
1299
+ } else {
1300
+ assert(false)
1301
+ }
1302
+
1303
+ return true
1304
+ }
1305
+
1306
+ /**
1307
+ * @param {AbortCallback} abort
1308
+ * @param {import('stream').Stream} body
1309
+ * @param {import('./client.js')} client
1310
+ * @param {import('../core/request.js')} request
1311
+ * @param {import('net').Socket} socket
1312
+ * @param {number} contentLength
1313
+ * @param {string} header
1314
+ * @param {boolean} expectsPayload
1315
+ */
1316
+ function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1317
+ assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined')
1318
+
1319
+ let finished = false
1320
+
1321
+ const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header })
1322
+
1323
+ /**
1324
+ * @param {Buffer} chunk
1325
+ * @returns {void}
1326
+ */
1327
+ const onData = function (chunk) {
1328
+ if (finished) {
1329
+ return
1330
+ }
1331
+
1332
+ try {
1333
+ if (!writer.write(chunk) && this.pause) {
1334
+ this.pause()
1335
+ }
1336
+ } catch (err) {
1337
+ util.destroy(this, err)
1338
+ }
1339
+ }
1340
+
1341
+ /**
1342
+ * @returns {void}
1343
+ */
1344
+ const onDrain = function () {
1345
+ if (finished) {
1346
+ return
1347
+ }
1348
+
1349
+ if (body.resume) {
1350
+ body.resume()
1351
+ }
1352
+ }
1353
+
1354
+ /**
1355
+ * @returns {void}
1356
+ */
1357
+ const onClose = function () {
1358
+ // 'close' might be emitted *before* 'error' for
1359
+ // broken streams. Wait a tick to avoid this case.
1360
+ queueMicrotask(() => {
1361
+ // It's only safe to remove 'error' listener after
1362
+ // 'close'.
1363
+ body.removeListener('error', onFinished)
1364
+ })
1365
+
1366
+ if (!finished) {
1367
+ const err = new RequestAbortedError()
1368
+ queueMicrotask(() => onFinished(err))
1369
+ }
1370
+ }
1371
+
1372
+ /**
1373
+ * @param {Error} [err]
1374
+ * @returns
1375
+ */
1376
+ const onFinished = function (err) {
1377
+ if (finished) {
1378
+ return
1379
+ }
1380
+
1381
+ finished = true
1382
+
1383
+ assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1))
1384
+
1385
+ socket
1386
+ .off('drain', onDrain)
1387
+ .off('error', onFinished)
1388
+
1389
+ body
1390
+ .removeListener('data', onData)
1391
+ .removeListener('end', onFinished)
1392
+ .removeListener('close', onClose)
1393
+
1394
+ if (!err) {
1395
+ try {
1396
+ writer.end()
1397
+ } catch (er) {
1398
+ err = er
1399
+ }
1400
+ }
1401
+
1402
+ writer.destroy(err)
1403
+
1404
+ if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) {
1405
+ util.destroy(body, err)
1406
+ } else {
1407
+ util.destroy(body)
1408
+ }
1409
+ }
1410
+
1411
+ body
1412
+ .on('data', onData)
1413
+ .on('end', onFinished)
1414
+ .on('error', onFinished)
1415
+ .on('close', onClose)
1416
+
1417
+ if (body.resume) {
1418
+ body.resume()
1419
+ }
1420
+
1421
+ socket
1422
+ .on('drain', onDrain)
1423
+ .on('error', onFinished)
1424
+
1425
+ if (body.errorEmitted ?? body.errored) {
1426
+ setImmediate(onFinished, body.errored)
1427
+ } else if (body.endEmitted ?? body.readableEnded) {
1428
+ setImmediate(onFinished, null)
1429
+ }
1430
+
1431
+ if (body.closeEmitted ?? body.closed) {
1432
+ setImmediate(onClose)
1433
+ }
1434
+ }
1435
+
1436
+ /**
1437
+ * @typedef AbortCallback
1438
+ * @type {Function}
1439
+ * @param {Error} [err]
1440
+ * @returns {void}
1441
+ */
1442
+
1443
+ /**
1444
+ * @param {AbortCallback} abort
1445
+ * @param {Uint8Array|null} body
1446
+ * @param {import('./client.js')} client
1447
+ * @param {import('../core/request.js')} request
1448
+ * @param {import('net').Socket} socket
1449
+ * @param {number} contentLength
1450
+ * @param {string} header
1451
+ * @param {boolean} expectsPayload
1452
+ * @returns {void}
1453
+ */
1454
+ function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1455
+ try {
1456
+ if (!body) {
1457
+ if (contentLength === 0) {
1458
+ socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
1459
+ } else {
1460
+ assert(contentLength === null, 'no body must not have content length')
1461
+ socket.write(`${header}\r\n`, 'latin1')
1462
+ }
1463
+ } else if (util.isBuffer(body)) {
1464
+ assert(contentLength === body.byteLength, 'buffer body must have content length')
1465
+
1466
+ socket.cork()
1467
+ socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1468
+ socket.write(body)
1469
+ socket.uncork()
1470
+ request.onBodySent(body)
1471
+
1472
+ if (!expectsPayload && request.reset !== false) {
1473
+ socket[kReset] = true
1474
+ }
1475
+ }
1476
+ request.onRequestSent()
1477
+
1478
+ client[kResume]()
1479
+ } catch (err) {
1480
+ abort(err)
1481
+ }
1482
+ }
1483
+
1484
+ /**
1485
+ * @param {AbortCallback} abort
1486
+ * @param {Blob} body
1487
+ * @param {import('./client.js')} client
1488
+ * @param {import('../core/request.js')} request
1489
+ * @param {import('net').Socket} socket
1490
+ * @param {number} contentLength
1491
+ * @param {string} header
1492
+ * @param {boolean} expectsPayload
1493
+ * @returns {Promise<void>}
1494
+ */
1495
+ async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1496
+ assert(contentLength === body.size, 'blob body must have content length')
1497
+
1498
+ try {
1499
+ if (contentLength != null && contentLength !== body.size) {
1500
+ throw new RequestContentLengthMismatchError()
1501
+ }
1502
+
1503
+ const buffer = Buffer.from(await body.arrayBuffer())
1504
+
1505
+ socket.cork()
1506
+ socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1507
+ socket.write(buffer)
1508
+ socket.uncork()
1509
+
1510
+ request.onBodySent(buffer)
1511
+ request.onRequestSent()
1512
+
1513
+ if (!expectsPayload && request.reset !== false) {
1514
+ socket[kReset] = true
1515
+ }
1516
+
1517
+ client[kResume]()
1518
+ } catch (err) {
1519
+ abort(err)
1520
+ }
1521
+ }
1522
+
1523
+ /**
1524
+ * @param {AbortCallback} abort
1525
+ * @param {Iterable} body
1526
+ * @param {import('./client.js')} client
1527
+ * @param {import('../core/request.js')} request
1528
+ * @param {import('net').Socket} socket
1529
+ * @param {number} contentLength
1530
+ * @param {string} header
1531
+ * @param {boolean} expectsPayload
1532
+ * @returns {Promise<void>}
1533
+ */
1534
+ async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1535
+ assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined')
1536
+
1537
+ let callback = null
1538
+ function onDrain () {
1539
+ if (callback) {
1540
+ const cb = callback
1541
+ callback = null
1542
+ cb()
1543
+ }
1544
+ }
1545
+
1546
+ const waitForDrain = () => new Promise((resolve, reject) => {
1547
+ assert(callback === null)
1548
+
1549
+ if (socket[kError]) {
1550
+ reject(socket[kError])
1551
+ } else {
1552
+ callback = resolve
1553
+ }
1554
+ })
1555
+
1556
+ socket
1557
+ .on('close', onDrain)
1558
+ .on('drain', onDrain)
1559
+
1560
+ const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header })
1561
+ try {
1562
+ // It's up to the user to somehow abort the async iterable.
1563
+ for await (const chunk of body) {
1564
+ if (socket[kError]) {
1565
+ throw socket[kError]
1566
+ }
1567
+
1568
+ if (!writer.write(chunk)) {
1569
+ await waitForDrain()
1570
+ }
1571
+ }
1572
+
1573
+ writer.end()
1574
+ } catch (err) {
1575
+ writer.destroy(err)
1576
+ } finally {
1577
+ socket
1578
+ .off('close', onDrain)
1579
+ .off('drain', onDrain)
1580
+ }
1581
+ }
1582
+
1583
+ class AsyncWriter {
1584
+ /**
1585
+ *
1586
+ * @param {object} arg
1587
+ * @param {AbortCallback} arg.abort
1588
+ * @param {import('net').Socket} arg.socket
1589
+ * @param {import('../core/request.js')} arg.request
1590
+ * @param {number} arg.contentLength
1591
+ * @param {import('./client.js')} arg.client
1592
+ * @param {boolean} arg.expectsPayload
1593
+ * @param {string} arg.header
1594
+ */
1595
+ constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) {
1596
+ this.socket = socket
1597
+ this.request = request
1598
+ this.contentLength = contentLength
1599
+ this.client = client
1600
+ this.bytesWritten = 0
1601
+ this.expectsPayload = expectsPayload
1602
+ this.header = header
1603
+ this.abort = abort
1604
+
1605
+ socket[kWriting] = true
1606
+ }
1607
+
1608
+ /**
1609
+ * @param {Buffer} chunk
1610
+ * @returns
1611
+ */
1612
+ write (chunk) {
1613
+ const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this
1614
+
1615
+ if (socket[kError]) {
1616
+ throw socket[kError]
1617
+ }
1618
+
1619
+ if (socket.destroyed) {
1620
+ return false
1621
+ }
1622
+
1623
+ const len = Buffer.byteLength(chunk)
1624
+ if (!len) {
1625
+ return true
1626
+ }
1627
+
1628
+ // We should defer writing chunks.
1629
+ if (contentLength !== null && bytesWritten + len > contentLength) {
1630
+ if (client[kStrictContentLength]) {
1631
+ throw new RequestContentLengthMismatchError()
1632
+ }
1633
+
1634
+ process.emitWarning(new RequestContentLengthMismatchError())
1635
+ }
1636
+
1637
+ socket.cork()
1638
+
1639
+ if (bytesWritten === 0) {
1640
+ if (!expectsPayload && request.reset !== false) {
1641
+ socket[kReset] = true
1642
+ }
1643
+
1644
+ if (contentLength === null) {
1645
+ socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1')
1646
+ } else {
1647
+ socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1648
+ }
1649
+ }
1650
+
1651
+ if (contentLength === null) {
1652
+ socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1')
1653
+ }
1654
+
1655
+ this.bytesWritten += len
1656
+
1657
+ const ret = socket.write(chunk)
1658
+
1659
+ socket.uncork()
1660
+
1661
+ request.onBodySent(chunk)
1662
+
1663
+ if (!ret) {
1664
+ if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
1665
+ if (socket[kParser].timeout.refresh) {
1666
+ socket[kParser].timeout.refresh()
1667
+ }
1668
+ }
1669
+ }
1670
+
1671
+ return ret
1672
+ }
1673
+
1674
+ /**
1675
+ * @returns {void}
1676
+ */
1677
+ end () {
1678
+ const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this
1679
+ request.onRequestSent()
1680
+
1681
+ socket[kWriting] = false
1682
+
1683
+ if (socket[kError]) {
1684
+ throw socket[kError]
1685
+ }
1686
+
1687
+ if (socket.destroyed) {
1688
+ return
1689
+ }
1690
+
1691
+ if (bytesWritten === 0) {
1692
+ if (expectsPayload) {
1693
+ // https://tools.ietf.org/html/rfc7230#section-3.3.2
1694
+ // A user agent SHOULD send a Content-Length in a request message when
1695
+ // no Transfer-Encoding is sent and the request method defines a meaning
1696
+ // for an enclosed payload body.
1697
+
1698
+ socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
1699
+ } else {
1700
+ socket.write(`${header}\r\n`, 'latin1')
1701
+ }
1702
+ } else if (contentLength === null) {
1703
+ socket.write('\r\n0\r\n\r\n', 'latin1')
1704
+ }
1705
+
1706
+ if (contentLength !== null && bytesWritten !== contentLength) {
1707
+ if (client[kStrictContentLength]) {
1708
+ throw new RequestContentLengthMismatchError()
1709
+ } else {
1710
+ process.emitWarning(new RequestContentLengthMismatchError())
1711
+ }
1712
+ }
1713
+
1714
+ if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
1715
+ if (socket[kParser].timeout.refresh) {
1716
+ socket[kParser].timeout.refresh()
1717
+ }
1718
+ }
1719
+
1720
+ client[kResume]()
1721
+ }
1722
+
1723
+ /**
1724
+ * @param {Error} [err]
1725
+ * @returns {void}
1726
+ */
1727
+ destroy (err) {
1728
+ const { socket, client, abort } = this
1729
+
1730
+ socket[kWriting] = false
1731
+
1732
+ if (err) {
1733
+ assert(client[kRunning] <= 1, 'pipeline should only contain this request')
1734
+ abort(err)
1735
+ }
1736
+ }
1737
+ }
1738
+
1739
+ module.exports = connectH1