nitro 3.0.260311-beta → 3.0.260415-beta

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 (206) hide show
  1. package/dist/_build/common.mjs +630 -1602
  2. package/dist/_build/rolldown.mjs +0 -11
  3. package/dist/_build/rollup.mjs +0 -13
  4. package/dist/_build/vite.build.mjs +0 -2
  5. package/dist/_chunks/nitro.mjs +23 -216
  6. package/dist/_chunks/nitro2.mjs +0 -2
  7. package/dist/_chunks/nitro3.mjs +128 -121
  8. package/dist/_chunks/nitro4.mjs +127 -0
  9. package/dist/_chunks/utils.mjs +0 -7
  10. package/dist/_common.mjs +0 -2
  11. package/dist/_dev.d.mts +0 -3
  12. package/dist/_dev.mjs +0 -10
  13. package/dist/_libs/_.mjs +0 -1
  14. package/dist/_libs/_3.mjs +0 -1
  15. package/dist/_libs/_5.mjs +0 -1
  16. package/dist/_libs/_6.mjs +0 -2
  17. package/dist/_libs/_7.mjs +0 -3
  18. package/dist/_libs/c12+rc9.mjs +24 -22
  19. package/dist/_libs/c12+readdirp+chokidar.d.mts +0 -7
  20. package/dist/_libs/citty.mjs +134 -31
  21. package/dist/_libs/commondir+is-reference.mjs +2 -9
  22. package/dist/_libs/compatx.d.mts +0 -2
  23. package/dist/_libs/compatx.mjs +0 -2
  24. package/dist/_libs/esbuild.d.mts +0 -1
  25. package/dist/_libs/escape-string-regexp.mjs +0 -2
  26. package/dist/_libs/estree+pluginutils.d.mts +0 -5
  27. package/dist/_libs/estree-walker.mjs +3 -88
  28. package/dist/_libs/hasown+resolve+deepmerge.mjs +22 -85
  29. package/dist/_libs/httpxy.d.mts +9 -5
  30. package/dist/_libs/httpxy.mjs +284 -116
  31. package/dist/_libs/klona.mjs +0 -2
  32. package/dist/_libs/magic-string.d.mts +0 -2
  33. package/dist/_libs/mlly.d.mts +0 -2
  34. package/dist/_libs/nypm+tinyexec.mjs +111 -134
  35. package/dist/_libs/perfect-debounce.mjs +0 -20
  36. package/dist/_libs/pkg-types.d.mts +0 -3
  37. package/dist/_libs/plugin-alias.mjs +0 -2
  38. package/dist/_libs/plugin-inject.mjs +0 -2
  39. package/dist/_libs/plugin-json.mjs +0 -2
  40. package/dist/_libs/pluginutils.mjs +0 -26
  41. package/dist/_libs/readdirp+chokidar.mjs +0 -173
  42. package/dist/_libs/remapping.mjs +0 -2
  43. package/dist/_libs/resolve-uri+gen-mapping.mjs +0 -32
  44. package/dist/_libs/rou3.d.mts +0 -4
  45. package/dist/_libs/rou3.mjs +0 -29
  46. package/dist/_libs/std-env.d.mts +1 -3
  47. package/dist/_libs/tsconfck.mjs +0 -294
  48. package/dist/_libs/ultrahtml.mjs +0 -2
  49. package/dist/_libs/unimport+unplugin.mjs +1 -44
  50. package/dist/_libs/unplugin+unimport.d.mts +0 -7
  51. package/dist/_libs/unwasm.d.mts +0 -3
  52. package/dist/_presets.mjs +211 -80
  53. package/dist/builder.d.mts +1 -22
  54. package/dist/builder.mjs +0 -11
  55. package/dist/cli/_chunks/build.mjs +0 -2
  56. package/dist/cli/_chunks/common.mjs +0 -2
  57. package/dist/cli/_chunks/deploy.mjs +0 -3
  58. package/dist/cli/_chunks/dev.mjs +0 -5
  59. package/dist/cli/_chunks/docs.mjs +1 -3
  60. package/dist/cli/_chunks/list.mjs +0 -2
  61. package/dist/cli/_chunks/prepare.mjs +0 -2
  62. package/dist/cli/_chunks/preview.mjs +1 -4
  63. package/dist/cli/_chunks/run.mjs +0 -2
  64. package/dist/cli/_chunks/task.mjs +0 -2
  65. package/dist/cli/index.mjs +0 -2
  66. package/{skills/nitro/docs/docs/quick-start.md → dist/docs/0.docs/1.quick-start.md} +4 -4
  67. package/{skills/nitro/docs/docs/lifecycle.md → dist/docs/0.docs/10.lifecycle.md} +4 -4
  68. package/dist/docs/0.docs/11.openapi.md +291 -0
  69. package/{skills/nitro/docs/docs/plugins.md → dist/docs/0.docs/12.plugins.md} +2 -2
  70. package/{skills/nitro/docs/docs/tasks.md → dist/docs/0.docs/13.tasks.md} +6 -6
  71. package/dist/docs/0.docs/14.websocket.md +386 -0
  72. package/{skills/nitro/docs/docs/migration.md → dist/docs/0.docs/15.migration.md} +2 -4
  73. package/{skills/nitro/docs/docs/renderer.md → dist/docs/0.docs/2.renderer.md} +8 -8
  74. package/{skills/nitro/docs/docs/routing.md → dist/docs/0.docs/3.routing.md} +34 -34
  75. package/{skills/nitro/docs/docs/server-entry.md → dist/docs/0.docs/4.server-entry.md} +6 -6
  76. package/{skills/nitro/docs/docs/cache.md → dist/docs/0.docs/5.cache.md} +12 -12
  77. package/{skills/nitro/docs/docs/storage.md → dist/docs/0.docs/6.storage.md} +6 -6
  78. package/{skills/nitro/docs/docs/assets.md → dist/docs/0.docs/7.assets.md} +8 -8
  79. package/{skills/nitro/docs/docs/configuration.md → dist/docs/0.docs/8.configuration.md} +16 -16
  80. package/{skills/nitro/docs/docs/database.md → dist/docs/0.docs/9.database.md} +6 -6
  81. package/{skills/nitro/docs/deploy → dist/docs/1.deploy/0.index}/index.md +3 -3
  82. package/{skills/nitro/docs/deploy/providers/aws.md → dist/docs/1.deploy/2.providers/1.aws.md} +4 -4
  83. package/{skills/nitro/docs/deploy/providers/iis.md → dist/docs/1.deploy/2.providers/15.iis.md} +2 -2
  84. package/{skills/nitro/docs/deploy/providers/aws-amplify.md → dist/docs/1.deploy/2.providers/2.aws-amplify.md} +2 -2
  85. package/{skills/nitro/docs/deploy/providers/vercel.md → dist/docs/1.deploy/2.providers/21.vercel.md} +98 -7
  86. package/{skills/nitro/docs/deploy/providers/zephyr.md → dist/docs/1.deploy/2.providers/23.zephyr.md} +2 -2
  87. package/{skills/nitro/docs/deploy/providers/cloudflare.md → dist/docs/1.deploy/2.providers/5.cloudflare.md} +9 -15
  88. package/dist/docs/1.deploy/2.providers/8.edgeone.md +20 -0
  89. package/{skills/nitro/docs/config → dist/docs/2.config/0.index}/index.md +165 -91
  90. package/{skills/nitro/docs/examples/hono.md → dist/docs/3.examples/10.hono.md} +1 -1
  91. package/{skills/nitro/docs/examples/import-alias.md → dist/docs/3.examples/11.import-alias.md} +1 -4
  92. package/{skills/nitro/docs/examples/mono-jsx.md → dist/docs/3.examples/13.mono-jsx.md} +2 -2
  93. package/{skills/nitro/docs/examples/plugins.md → dist/docs/3.examples/15.plugins.md} +4 -4
  94. package/{skills/nitro/docs/examples/shiki.md → dist/docs/3.examples/19.shiki.md} +1 -1
  95. package/{skills/nitro/docs/examples/auto-imports.md → dist/docs/3.examples/2.auto-imports.md} +0 -1
  96. package/{skills/nitro/docs/examples/vite-nitro-plugin.md → dist/docs/3.examples/21.vite-nitro-plugin.md} +1 -1
  97. package/{skills/nitro/docs/examples/vite-rsc.md → dist/docs/3.examples/22.vite-rsc.md} +4 -4
  98. package/{skills/nitro/docs/examples/vite-ssr-html.md → dist/docs/3.examples/23.vite-ssr-html.md} +3 -3
  99. package/{skills/nitro/docs/examples/vite-ssr-preact.md → dist/docs/3.examples/24.vite-ssr-preact.md} +6 -6
  100. package/{skills/nitro/docs/examples/vite-ssr-react.md → dist/docs/3.examples/25.vite-ssr-react.md} +3 -3
  101. package/{skills/nitro/docs/examples/vite-ssr-solid.md → dist/docs/3.examples/26.vite-ssr-solid.md} +3 -3
  102. package/{skills/nitro/docs/examples/vite-ssr-tsr-react.md → dist/docs/3.examples/27.vite-ssr-tsr-react.md} +6 -6
  103. package/{skills/nitro/docs/examples/vite-ssr-tss-react.md → dist/docs/3.examples/28.vite-ssr-tss-react.md} +11 -11
  104. package/{skills/nitro/docs/examples/vite-ssr-vue-router.md → dist/docs/3.examples/29.vite-ssr-vue-router.md} +6 -5
  105. package/{skills/nitro/docs/examples/vite-trpc.md → dist/docs/3.examples/30.vite-trpc.md} +3 -3
  106. package/{skills/nitro/docs/examples/elysia.md → dist/docs/3.examples/6.elysia.md} +1 -1
  107. package/{skills/nitro/docs/examples/fastify.md → dist/docs/3.examples/8.fastify.md} +1 -1
  108. package/dist/docs/README.md +86 -0
  109. package/dist/node_modules/@speed-highlight/core/dist/index.js +4 -4
  110. package/dist/node_modules/@speed-highlight/core/dist/terminal.js +2 -2
  111. package/dist/node_modules/@speed-highlight/core/package.json +1 -1
  112. package/dist/node_modules/cookie-es/dist/index.mjs +299 -250
  113. package/dist/node_modules/cookie-es/package.json +26 -23
  114. package/dist/node_modules/defu/dist/defu.mjs +2 -2
  115. package/dist/node_modules/defu/package.json +33 -28
  116. package/dist/node_modules/rendu/dist/_chunks/libs/cookie-es.mjs +151 -0
  117. package/dist/node_modules/rendu/dist/index.mjs +5 -112
  118. package/dist/node_modules/rendu/package.json +25 -24
  119. package/dist/node_modules/youch/package.json +2 -2
  120. package/dist/presets/_nitro/runtime/nitro-dev.mjs +3 -1
  121. package/dist/presets/_nitro/runtime/service-worker.mjs +1 -1
  122. package/dist/presets/aws-lambda/runtime/_utils.mjs +6 -6
  123. package/dist/presets/azure/runtime/_utils.mjs +5 -5
  124. package/dist/presets/azure/runtime/azure-swa.mjs +5 -5
  125. package/dist/presets/bun/runtime/bun.mjs +5 -3
  126. package/dist/presets/cloudflare/runtime/_module-handler.mjs +1 -1
  127. package/dist/presets/cloudflare/runtime/cloudflare-durable.mjs +4 -4
  128. package/dist/presets/cloudflare/runtime/cloudflare-module.mjs +3 -3
  129. package/dist/presets/cloudflare/runtime/cloudflare-pages.mjs +2 -2
  130. package/dist/presets/cloudflare/runtime/plugin.dev.mjs +10 -21
  131. package/dist/presets/deno/runtime/deno-deploy.mjs +4 -4
  132. package/dist/presets/deno/runtime/deno-server.mjs +5 -3
  133. package/dist/presets/edgeone/runtime/edgeone.mjs +10 -0
  134. package/dist/presets/netlify/runtime/netlify-edge.mjs +2 -2
  135. package/dist/presets/node/runtime/node-cluster.mjs +2 -2
  136. package/dist/presets/node/runtime/node-middleware.mjs +1 -1
  137. package/dist/presets/node/runtime/node-server.mjs +5 -3
  138. package/dist/presets/stormkit/runtime/stormkit.mjs +1 -1
  139. package/dist/presets/vercel/runtime/cron-handler.mjs +1 -1
  140. package/dist/presets/vercel/runtime/queue-handler.mjs +21 -0
  141. package/dist/presets/vercel/runtime/vercel.node.mjs +3 -3
  142. package/dist/presets/vercel/runtime/vercel.web.mjs +1 -1
  143. package/dist/presets/winterjs/runtime/winterjs.mjs +10 -10
  144. package/dist/runtime/internal/app.mjs +12 -11
  145. package/dist/runtime/internal/context.mjs +1 -9
  146. package/dist/runtime/internal/error/dev.mjs +10 -10
  147. package/dist/runtime/internal/route-rules.d.mts +3 -1
  148. package/dist/runtime/internal/route-rules.mjs +9 -7
  149. package/dist/runtime/internal/routes/dev-tasks.mjs +13 -12
  150. package/dist/runtime/internal/routes/openapi.mjs +2 -2
  151. package/dist/runtime/internal/routes/scalar.mjs +3 -3
  152. package/dist/runtime/internal/routes/swagger.mjs +7 -4
  153. package/dist/runtime/internal/runtime-config.mjs +2 -2
  154. package/dist/runtime/internal/task.mjs +5 -5
  155. package/dist/runtime/meta.d.mts +1 -0
  156. package/dist/runtime/meta.mjs +1 -0
  157. package/dist/runtime/nitro.mjs +3 -3
  158. package/dist/runtime/virtual/renderer-template.mjs +1 -1
  159. package/dist/runtime/virtual/tracing.d.mts +5 -0
  160. package/dist/runtime/virtual/tracing.mjs +1 -0
  161. package/dist/types/index.d.mts +155 -86
  162. package/dist/vite.d.mts +0 -5
  163. package/dist/vite.mjs +57 -28
  164. package/lib/tsconfig.json +3 -5
  165. package/package.json +56 -54
  166. package/skills/nitro/SKILL.md +0 -10
  167. package/skills/nitro/docs/TOC.md +0 -83
  168. package/skills/nitro/docs/_navigation.json +0 -679
  169. /package/{skills/nitro/docs/docs → dist/docs/0.docs/0.index}/index.md +0 -0
  170. /package/{skills/nitro/docs/docs/nightly.md → dist/docs/0.docs/16.nightly.md} +0 -0
  171. /package/{skills/nitro/docs/deploy/runtimes/node.md → dist/docs/1.deploy/1.runtimes/0.node.md} +0 -0
  172. /package/{skills/nitro/docs/deploy/runtimes/bun.md → dist/docs/1.deploy/1.runtimes/1.bun.md} +0 -0
  173. /package/{skills/nitro/docs/deploy/runtimes/deno.md → dist/docs/1.deploy/1.runtimes/2.deno.md} +0 -0
  174. /package/{skills/nitro/docs/deploy/providers/alwaysdata.md → dist/docs/1.deploy/2.providers/0.alwaysdata.md} +0 -0
  175. /package/{skills/nitro/docs/deploy/providers/flightcontrol.md → dist/docs/1.deploy/2.providers/10.flightcontrol.md} +0 -0
  176. /package/{skills/nitro/docs/deploy/providers/genezio.md → dist/docs/1.deploy/2.providers/11.genezio.md} +0 -0
  177. /package/{skills/nitro/docs/deploy/providers/github-pages.md → dist/docs/1.deploy/2.providers/12.github-pages.md} +0 -0
  178. /package/{skills/nitro/docs/deploy/providers/gitlab-pages.md → dist/docs/1.deploy/2.providers/13.gitlab-pages.md} +0 -0
  179. /package/{skills/nitro/docs/deploy/providers/heroku.md → dist/docs/1.deploy/2.providers/14.heroku.md} +0 -0
  180. /package/{skills/nitro/docs/deploy/providers/koyeb.md → dist/docs/1.deploy/2.providers/16.koyeb.md} +0 -0
  181. /package/{skills/nitro/docs/deploy/providers/netlify.md → dist/docs/1.deploy/2.providers/17.netlify.md} +0 -0
  182. /package/{skills/nitro/docs/deploy/providers/platform-sh.md → dist/docs/1.deploy/2.providers/18.platform-sh.md} +0 -0
  183. /package/{skills/nitro/docs/deploy/providers/render.md → dist/docs/1.deploy/2.providers/19.render.md} +0 -0
  184. /package/{skills/nitro/docs/deploy/providers/stormkit.md → dist/docs/1.deploy/2.providers/20.stormkit.md} +0 -0
  185. /package/{skills/nitro/docs/deploy/providers/zeabur.md → dist/docs/1.deploy/2.providers/22.zeabur.md} +0 -0
  186. /package/{skills/nitro/docs/deploy/providers/zerops.md → dist/docs/1.deploy/2.providers/24.zerops.md} +0 -0
  187. /package/{skills/nitro/docs/deploy/providers/azure.md → dist/docs/1.deploy/2.providers/3.azure.md} +0 -0
  188. /package/{skills/nitro/docs/deploy/providers/cleavr.md → dist/docs/1.deploy/2.providers/4.cleavr.md} +0 -0
  189. /package/{skills/nitro/docs/deploy/providers/deno-deploy.md → dist/docs/1.deploy/2.providers/6.deno-deploy.md} +0 -0
  190. /package/{skills/nitro/docs/deploy/providers/digitalocean.md → dist/docs/1.deploy/2.providers/7.digitalocean.md} +0 -0
  191. /package/{skills/nitro/docs/deploy/providers/firebase.md → dist/docs/1.deploy/2.providers/9.firebase.md} +0 -0
  192. /package/{skills/nitro/docs/examples → dist/docs/3.examples/0.index}/index.md +0 -0
  193. /package/{skills/nitro/docs/examples/api-routes.md → dist/docs/3.examples/1.api-routes.md} +0 -0
  194. /package/{skills/nitro/docs/examples/middleware.md → dist/docs/3.examples/12.middleware.md} +0 -0
  195. /package/{skills/nitro/docs/examples/nano-jsx.md → dist/docs/3.examples/14.nano-jsx.md} +0 -0
  196. /package/{skills/nitro/docs/examples/renderer.md → dist/docs/3.examples/16.renderer.md} +0 -0
  197. /package/{skills/nitro/docs/examples/runtime-config.md → dist/docs/3.examples/17.runtime-config.md} +0 -0
  198. /package/{skills/nitro/docs/examples/server-fetch.md → dist/docs/3.examples/18.server-fetch.md} +0 -0
  199. /package/{skills/nitro/docs/examples/virtual-routes.md → dist/docs/3.examples/20.virtual-routes.md} +0 -0
  200. /package/{skills/nitro/docs/examples/cached-handler.md → dist/docs/3.examples/3.cached-handler.md} +0 -0
  201. /package/{skills/nitro/docs/examples/websocket.md → dist/docs/3.examples/31.websocket.md} +0 -0
  202. /package/{skills/nitro/docs/examples/custom-error-handler.md → dist/docs/3.examples/4.custom-error-handler.md} +0 -0
  203. /package/{skills/nitro/docs/examples/database.md → dist/docs/3.examples/5.database.md} +0 -0
  204. /package/{skills/nitro/docs/examples/express.md → dist/docs/3.examples/7.express.md} +0 -0
  205. /package/{skills/nitro/docs/examples/hello-world.md → dist/docs/3.examples/9.hello-world.md} +0 -0
  206. /package/{skills/nitro → dist}/docs/index.md +0 -0
@@ -1,10 +1,28 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { Readable } from "node:stream";
3
3
  import http, { request } from "node:http";
4
- import nodeHTTPS, { request as request$1 } from "node:https";
5
- //#region node_modules/.pnpm/httpxy@0.3.1/node_modules/httpxy/dist/index.mjs
4
+ import https, { request as request$1 } from "node:https";
5
+ import http2 from "node:http2";
6
6
  const upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i;
7
+ const defaultAgents = {
8
+ http: new http.Agent({
9
+ keepAlive: true,
10
+ maxSockets: 256,
11
+ maxFreeSockets: 64
12
+ }),
13
+ https: new https.Agent({
14
+ keepAlive: true,
15
+ maxSockets: 256,
16
+ maxFreeSockets: 64
17
+ })
18
+ };
7
19
  const isSSL = /^https|wss/;
20
+ const HTTP2_HEADER_BLACKLIST = [
21
+ ":method",
22
+ ":path",
23
+ ":scheme",
24
+ ":authority"
25
+ ];
8
26
  function setupOutgoing(outgoing, options, req, forward) {
9
27
  outgoing.port = options[forward || "target"].port || (isSSL.test(options[forward || "target"].protocol ?? "http") ? 443 : 80);
10
28
  for (const e of [
@@ -18,17 +36,24 @@ function setupOutgoing(outgoing, options, req, forward) {
18
36
  "ca",
19
37
  "ciphers",
20
38
  "secureProtocol"
21
- ]) outgoing[e] = options[forward || "target"][e];
39
+ ]) {
40
+ const value = options[forward || "target"][e];
41
+ if (value !== void 0) outgoing[e] = value;
42
+ }
22
43
  outgoing.method = options.method || req.method;
23
44
  outgoing.headers = { ...req.headers };
24
- if (options.headers) outgoing.headers = {
25
- ...outgoing.headers,
26
- ...options.headers
27
- };
45
+ if (req.headers?.[":authority"]) outgoing.headers.host = req.headers[":authority"];
46
+ if (options.headers) for (const key of Object.keys(options.headers)) outgoing.headers[key] = options.headers[key];
47
+ if (req.httpVersionMajor > 1) for (const header of HTTP2_HEADER_BLACKLIST) delete outgoing.headers[header];
28
48
  if (options.auth) outgoing.auth = options.auth;
29
49
  if (options.ca) outgoing.ca = options.ca;
30
50
  if (isSSL.test(options[forward || "target"].protocol ?? "http")) outgoing.rejectUnauthorized = options.secure === void 0 ? true : options.secure;
31
- outgoing.agent = options.agent || false;
51
+ if (options.agent !== void 0) outgoing.agent = options.agent || false;
52
+ else if (req.httpVersionMajor > 1) outgoing.agent = false;
53
+ else {
54
+ const targetProto = options[forward || "target"].protocol ?? "http";
55
+ outgoing.agent = isSSL.test(targetProto) ? defaultAgents.https : defaultAgents.http;
56
+ }
32
57
  outgoing.localAddress = options.localAddress;
33
58
  if (!outgoing.agent) {
34
59
  outgoing.headers = outgoing.headers || {};
@@ -36,6 +61,7 @@ function setupOutgoing(outgoing, options, req, forward) {
36
61
  }
37
62
  const target = options[forward || "target"];
38
63
  const targetPath = target && options.prependPath !== false ? target.pathname || "" : "";
64
+ const targetSearch = target instanceof URL && options.prependPath !== false ? target.search || "" : "";
39
65
  const reqUrl = req.url || "";
40
66
  const qIdx = reqUrl.indexOf("?");
41
67
  const reqPath = qIdx === -1 ? reqUrl : reqUrl.slice(0, qIdx);
@@ -43,7 +69,9 @@ function setupOutgoing(outgoing, options, req, forward) {
43
69
  const normalizedPath = reqPath ? reqPath[0] === "/" ? reqPath : "/" + reqPath : "/";
44
70
  let outgoingPath = options.toProxy ? "/" + reqUrl : normalizedPath + reqSearch;
45
71
  outgoingPath = options.ignorePath ? "" : outgoingPath;
46
- outgoing.path = joinURL(targetPath, outgoingPath);
72
+ let fullPath = joinURL(targetPath, outgoingPath);
73
+ if (targetSearch) fullPath = fullPath.includes("?") ? fullPath.replace("?", targetSearch + "&") : fullPath + targetSearch;
74
+ outgoing.path = fullPath;
47
75
  if (options.changeOrigin) outgoing.headers.host = requiresPort(outgoing.port, options[forward || "target"].protocol) && !hasPort(outgoing.host) ? outgoing.host + ":" + outgoing.port : outgoing.host ?? void 0;
48
76
  return outgoing;
49
77
  }
@@ -63,12 +91,14 @@ function setupSocket(socket) {
63
91
  return socket;
64
92
  }
65
93
  function getPort(req) {
66
- const res = req.headers.host ? req.headers.host.match(/:(\d+)/) : "";
94
+ const hostHeader = req.headers[":authority"] || req.headers.host;
95
+ const res = hostHeader ? hostHeader.match(/:(\d+)/) : "";
67
96
  if (res) return res[1];
68
97
  return hasEncryptedConnection(req) ? "443" : "80";
69
98
  }
70
99
  function hasEncryptedConnection(req) {
71
- return Boolean(req.connection.encrypted || req.connection.pair);
100
+ const socket = req.socket;
101
+ return !!socket && "encrypted" in socket && socket.encrypted;
72
102
  }
73
103
  function rewriteCookieProperty(header, config, property) {
74
104
  if (Array.isArray(header)) return header.map(function(headerElement) {
@@ -118,22 +148,26 @@ function defineProxyMiddleware(m) {
118
148
  function defineProxyOutgoingMiddleware(m) {
119
149
  return m;
120
150
  }
121
- const redirectRegex = /^201|30([1278])$/;
151
+ const redirectRegex = /^201|30([12378])$/;
122
152
  const webOutgoingMiddleware = [
123
153
  defineProxyOutgoingMiddleware((req, res, proxyRes) => {
124
- if (req.httpVersion === "1.0") delete proxyRes.headers["transfer-encoding"];
154
+ if (req.httpVersion === "1.0" || req.httpVersionMajor >= 2 || proxyRes.statusCode === 204 || proxyRes.statusCode === 304) delete proxyRes.headers["transfer-encoding"];
125
155
  }),
126
156
  defineProxyOutgoingMiddleware((req, res, proxyRes) => {
127
157
  if (req.httpVersion === "1.0") proxyRes.headers.connection = req.headers.connection || "close";
128
- else if (req.httpVersion !== "2.0" && !proxyRes.headers.connection) proxyRes.headers.connection = req.headers.connection || "keep-alive";
158
+ else if (req.httpVersionMajor < 2 && !proxyRes.headers.connection) proxyRes.headers.connection = req.headers.connection || "keep-alive";
159
+ else if (req.httpVersionMajor >= 2) delete proxyRes.headers.connection;
129
160
  }),
130
161
  defineProxyOutgoingMiddleware((req, res, proxyRes, options) => {
131
162
  if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite) && proxyRes.headers.location && redirectRegex.test(String(proxyRes.statusCode))) {
132
- const target = options.target instanceof URL ? options.target : new URL(options.target);
133
- const u = new URL(proxyRes.headers.location);
163
+ const target = _toURL(options.target);
164
+ const u = new URL(proxyRes.headers.location, target);
134
165
  if (target.host !== u.host) return;
135
166
  if (options.hostRewrite) u.host = options.hostRewrite;
136
- else if (options.autoRewrite && req.headers.host) u.host = req.headers.host;
167
+ else if (options.autoRewrite) {
168
+ if (req.headers[":authority"]) u.host = req.headers[":authority"];
169
+ else if (req.headers.host) u.host = req.headers.host;
170
+ }
137
171
  if (options.protocolRewrite) u.protocol = options.protocolRewrite;
138
172
  proxyRes.headers.location = u.toString();
139
173
  }
@@ -144,10 +178,12 @@ const webOutgoingMiddleware = [
144
178
  const preserveHeaderKeyCase = options.preserveHeaderKeyCase;
145
179
  let rawHeaderKeyMap;
146
180
  const setHeader = function(key, header) {
147
- if (header === void 0) return;
181
+ if (header === void 0 || !String(key).trim()) return;
148
182
  if (rewriteCookieDomainConfig && key.toLowerCase() === "set-cookie") header = rewriteCookieProperty(header, rewriteCookieDomainConfig, "domain");
149
183
  if (rewriteCookiePathConfig && key.toLowerCase() === "set-cookie") header = rewriteCookieProperty(header, rewriteCookiePathConfig, "path");
150
- res.setHeader(String(key).trim(), header);
184
+ try {
185
+ res.setHeader(String(key).trim(), header);
186
+ } catch {}
151
187
  };
152
188
  if (preserveHeaderKeyCase && proxyRes.rawHeaders !== void 0) {
153
189
  rawHeaderKeyMap = {};
@@ -163,17 +199,23 @@ const webOutgoingMiddleware = [
163
199
  }
164
200
  }),
165
201
  defineProxyOutgoingMiddleware((req, res, proxyRes) => {
166
- if (proxyRes.statusMessage) {
167
- res.statusCode = proxyRes.statusCode;
168
- res.statusMessage = proxyRes.statusMessage;
169
- } else res.statusCode = proxyRes.statusCode;
202
+ res.statusCode = proxyRes.statusCode;
203
+ if (proxyRes.statusMessage && req.httpVersionMajor < 2) res.statusMessage = proxyRes.statusMessage;
170
204
  })
171
205
  ];
206
+ function _toURL(target) {
207
+ if (target instanceof URL) return target;
208
+ if (typeof target === "string") return new URL(target);
209
+ const protocol = target.protocol || "http:";
210
+ const host = target.host || target.hostname || "localhost";
211
+ const port = target.port;
212
+ return new URL(`${protocol}//${host}${port ? ":" + port : ""}`);
213
+ }
172
214
  const nativeAgents = {
173
215
  http,
174
- https: nodeHTTPS
216
+ https
175
217
  };
176
- const redirectStatuses = /* @__PURE__ */ new Set([
218
+ const redirectStatuses = new Set([
177
219
  301,
178
220
  302,
179
221
  303,
@@ -204,8 +246,11 @@ const webIncomingMiddleware = [
204
246
  "for",
205
247
  "port",
206
248
  "proto"
207
- ]) req.headers["x-forwarded-" + header] = (req.headers["x-forwarded-" + header] || "") + (req.headers["x-forwarded-" + header] ? "," : "") + values[header];
208
- req.headers["x-forwarded-host"] = req.headers["x-forwarded-host"] || req.headers.host || "";
249
+ ]) {
250
+ const key = "x-forwarded-" + header;
251
+ if (!req.headers[key]) req.headers[key] = values[header];
252
+ }
253
+ req.headers["x-forwarded-host"] = req.headers["x-forwarded-host"] || req.headers[":authority"] || req.headers.host || "";
209
254
  }),
210
255
  defineProxyMiddleware((req, res, options, server, head, callback) => {
211
256
  server.emit("start", req, res, options.target || options.forward);
@@ -213,7 +258,7 @@ const webIncomingMiddleware = [
213
258
  const https = nativeAgents.https;
214
259
  const maxRedirects = typeof options.followRedirects === "number" ? options.followRedirects : options.followRedirects ? 5 : 0;
215
260
  if (options.forward) {
216
- const forwardReq = (options.forward.protocol === "https:" ? https : http).request(setupOutgoing(options.ssl || {}, options, req, "forward"));
261
+ const forwardReq = (isSSL.test(options.forward.protocol || "http") ? https : http).request(setupOutgoing(options.ssl || {}, options, req, "forward"));
217
262
  const forwardError = createErrorHandler(forwardReq, options.forward);
218
263
  req.on("error", forwardError);
219
264
  forwardReq.on("error", forwardError);
@@ -223,15 +268,12 @@ const webIncomingMiddleware = [
223
268
  return;
224
269
  }
225
270
  }
226
- const proxyReq = (options.target.protocol === "https:" ? https : http).request(setupOutgoing(options.ssl || {}, options, req));
271
+ const proxyReq = (isSSL.test(options.target.protocol || "http") ? https : http).request(setupOutgoing(options.ssl || {}, options, req));
227
272
  proxyReq.on("socket", (_socket) => {
228
273
  if (server && !proxyReq.getHeader("expect")) server.emit("proxyReq", proxyReq, req, res, options);
229
274
  });
230
275
  if (options.proxyTimeout) proxyReq.setTimeout(options.proxyTimeout, function() {
231
- proxyReq.abort();
232
- });
233
- req.on("aborted", function() {
234
- proxyReq.abort();
276
+ proxyReq.destroy();
235
277
  });
236
278
  res.on("close", function() {
237
279
  if (!res.writableFinished) proxyReq.destroy();
@@ -239,11 +281,11 @@ const webIncomingMiddleware = [
239
281
  const proxyError = createErrorHandler(proxyReq, options.target);
240
282
  req.on("error", proxyError);
241
283
  proxyReq.on("error", proxyError);
242
- function createErrorHandler(proxyReq2, url) {
243
- return function proxyError2(err) {
244
- if (req.socket.destroyed && err.code === "ECONNRESET") {
284
+ function createErrorHandler(proxyReq, url) {
285
+ return function proxyError(err) {
286
+ if (!req.socket?.writable && err.code === "ECONNRESET") {
245
287
  server.emit("econnreset", err, req, res, url);
246
- return proxyReq2.abort();
288
+ return proxyReq.destroy();
247
289
  }
248
290
  if (callback) callback(err, req, res, url);
249
291
  else server.emit("error", err, req, res, url);
@@ -264,7 +306,10 @@ const webIncomingMiddleware = [
264
306
  source.on("error", (err) => {
265
307
  proxyReq.destroy(err);
266
308
  });
267
- } else (options.buffer || req).pipe(proxyReq);
309
+ } else proxyReq.on("socket", (socket) => {
310
+ if (socket.pending) socket.on("connect", () => (options.buffer || req).pipe(proxyReq));
311
+ else (options.buffer || req).pipe(proxyReq);
312
+ });
268
313
  function handleResponse(proxyRes, redirectCount, currentUrl) {
269
314
  const statusCode = proxyRes.statusCode;
270
315
  if (maxRedirects > 0 && redirectStatuses.has(statusCode) && redirectCount < maxRedirects && proxyRes.headers.location) {
@@ -272,7 +317,7 @@ const webIncomingMiddleware = [
272
317
  const location = new URL(proxyRes.headers.location, currentUrl);
273
318
  const preserveMethod = statusCode === 307 || statusCode === 308;
274
319
  const redirectMethod = preserveMethod ? req.method || "GET" : "GET";
275
- const isHTTPS = location.protocol === "https:";
320
+ const isHTTPS = isSSL.test(location.protocol);
276
321
  const agent = isHTTPS ? https : http;
277
322
  const redirectHeaders = { ...req.headers };
278
323
  if (options.headers) Object.assign(redirectHeaders, options.headers);
@@ -298,7 +343,7 @@ const webIncomingMiddleware = [
298
343
  const redirectReq = agent.request(redirectOpts);
299
344
  if (server && !redirectReq.getHeader("expect")) server.emit("proxyReq", redirectReq, req, res, options);
300
345
  if (options.proxyTimeout) redirectReq.setTimeout(options.proxyTimeout, () => {
301
- redirectReq.abort();
346
+ redirectReq.destroy();
302
347
  });
303
348
  const redirectError = createErrorHandler(redirectReq, location);
304
349
  redirectReq.on("error", redirectError);
@@ -319,6 +364,13 @@ const webIncomingMiddleware = [
319
364
  res.on("close", function() {
320
365
  proxyRes.destroy();
321
366
  });
367
+ proxyRes.on("close", function() {
368
+ if (!proxyRes.complete && !res.destroyed) res.destroy();
369
+ });
370
+ proxyRes.on("error", function(err) {
371
+ if (!res.destroyed) res.destroy(err);
372
+ if (server.listenerCount("error") > 0) server.emit("error", err, req, res, currentUrl);
373
+ });
322
374
  proxyRes.on("end", function() {
323
375
  if (server) server.emit("end", req, res, proxyRes);
324
376
  });
@@ -352,37 +404,42 @@ const websocketIncomingMiddleware = [
352
404
  "for",
353
405
  "port",
354
406
  "proto"
355
- ]) req.headers["x-forwarded-" + header] = (req.headers["x-forwarded-" + header] || "") + (req.headers["x-forwarded-" + header] ? "," : "") + values[header];
407
+ ]) {
408
+ const key = "x-forwarded-" + header;
409
+ if (!req.headers[key]) req.headers[key] = values[header];
410
+ }
356
411
  }),
357
412
  defineProxyMiddleware((req, socket, options, server, head, callback) => {
358
413
  const createHttpHeader = function(line, headers) {
359
- return Object.keys(headers).reduce(function(head2, key) {
414
+ return Object.keys(headers).reduce(function(head, key) {
360
415
  const value = headers[key];
361
416
  if (!Array.isArray(value)) {
362
- head2.push(key + ": " + value);
363
- return head2;
417
+ head.push(key + ": " + value);
418
+ return head;
364
419
  }
365
- for (const element of value) head2.push(key + ": " + element);
366
- return head2;
420
+ for (const element of value) head.push(key + ": " + element);
421
+ return head;
367
422
  }, [line]).join("\r\n") + "\r\n\r\n";
368
423
  };
369
424
  setupSocket(socket);
370
425
  if (head && head.length > 0) socket.unshift(head);
371
426
  socket.on("error", onSocketError);
372
- const proxyReq = (isSSL.test(options.target.protocol || "http") ? nodeHTTPS : http).request(setupOutgoing(options.ssl || {}, options, req));
427
+ const proxyReq = (isSSL.test(options.target.protocol || "http") ? https : http).request(setupOutgoing(options.ssl || {}, options, req));
373
428
  if (server) server.emit("proxyReqWs", proxyReq, req, socket, options, head);
374
429
  proxyReq.on("error", onOutgoingError);
375
430
  proxyReq.on("response", function(res) {
376
- if (!res.upgrade) {
431
+ if (!res.upgrade) if (!socket.destroyed && socket.writable) {
377
432
  socket.write(createHttpHeader("HTTP/" + res.httpVersion + " " + res.statusCode + " " + res.statusMessage, res.headers));
433
+ res.on("error", onOutgoingError);
378
434
  res.pipe(socket);
379
- }
435
+ } else res.resume();
380
436
  });
381
437
  proxyReq.on("upgrade", function(proxyRes, proxySocket, proxyHead) {
382
438
  proxySocket.on("error", onOutgoingError);
383
439
  proxySocket.on("end", function() {
384
440
  server.emit("close", proxyRes, proxySocket, proxyHead);
385
441
  });
442
+ socket.removeListener("error", onSocketError);
386
443
  socket.on("error", function() {
387
444
  proxySocket.end();
388
445
  });
@@ -413,10 +470,6 @@ var ProxyServer = class extends EventEmitter {
413
470
  options;
414
471
  web;
415
472
  ws;
416
- /**
417
- * Creates the proxy server with specified options.
418
- * @param options - Config object passed to the proxy
419
- */
420
473
  constructor(options = {}) {
421
474
  super();
422
475
  this.options = options || {};
@@ -424,25 +477,24 @@ var ProxyServer = class extends EventEmitter {
424
477
  this.web = _createProxyFn("web", this);
425
478
  this.ws = _createProxyFn("ws", this);
426
479
  }
427
- /**
428
- * A function that wraps the object in a webserver, for your convenience
429
- * @param port - Port to listen on
430
- * @param hostname - The hostname to listen on
431
- */
432
480
  listen(port, hostname) {
433
481
  const closure = (req, res) => {
434
- this.web(req, res);
482
+ return this.web(req, res);
435
483
  };
436
- this._server = this.options.ssl ? nodeHTTPS.createServer(this.options.ssl, closure) : http.createServer(closure);
484
+ if (this.options.http2) {
485
+ if (!this.options.ssl) throw new Error("HTTP/2 requires ssl option");
486
+ this._server = http2.createSecureServer({
487
+ ...this.options.ssl,
488
+ allowHTTP1: true
489
+ }, closure);
490
+ } else if (this.options.ssl) this._server = https.createServer(this.options.ssl, closure);
491
+ else this._server = http.createServer(closure);
437
492
  if (this.options.ws) this._server.on("upgrade", (req, socket, head) => {
438
- this.ws(req, socket, head).catch(() => {});
493
+ this.ws(req, socket, this.options, head).catch(() => {});
439
494
  });
440
495
  this._server.listen(port, hostname);
441
496
  return this;
442
497
  }
443
- /**
444
- * A function that closes the inner webserver and stops listening on given port
445
- */
446
498
  close(callback) {
447
499
  if (this._server) this._server.close((...args) => {
448
500
  this._server = void 0;
@@ -465,7 +517,6 @@ var ProxyServer = class extends EventEmitter {
465
517
  if (i === false) throw new Error("No such pass");
466
518
  passes.splice(i++, 0, pass);
467
519
  }
468
- /** @internal */
469
520
  _getPasses(type) {
470
521
  return type === "ws" ? this._wsPasses : this._webPasses;
471
522
  }
@@ -496,20 +547,39 @@ function _createProxyFn(type, server) {
496
547
  res.on("error", (error) => {
497
548
  _reject(error);
498
549
  });
499
- for (const pass of server._getPasses(type)) if (pass(req, res, requestOptions, server, head, (error) => {
500
- if (server.listenerCount("error") > 0) {
501
- server.emit("error", error, req, res);
550
+ for (const pass of server._getPasses(type)) {
551
+ let stop;
552
+ try {
553
+ stop = pass(req, res, requestOptions, server, head, (error) => {
554
+ if (server.listenerCount("error") > 0) {
555
+ server.emit("error", error, req, res);
556
+ _resolve();
557
+ } else _reject(error);
558
+ });
559
+ } catch (error) {
560
+ if (server.listenerCount("error") > 0) {
561
+ server.emit("error", error, req, res);
562
+ _resolve();
563
+ } else _reject(error);
564
+ break;
565
+ }
566
+ if (stop) {
502
567
  _resolve();
503
- } else _reject(error);
504
- })) {
505
- _resolve();
506
- break;
568
+ break;
569
+ }
507
570
  }
508
571
  return callbackPromise;
509
572
  };
510
573
  }
511
- async function proxyFetch(addr, input, inputInit) {
574
+ async function proxyFetch(addr, input, inputInit, opts) {
512
575
  const resolvedAddr = parseAddr(addr);
576
+ let useHTTPS = false;
577
+ let addrBasePath = "";
578
+ if (typeof addr === "string" && !addr.startsWith("unix:")) {
579
+ const addrURL = new URL(addr);
580
+ useHTTPS = isSSL.test(addrURL.protocol);
581
+ if (addrURL.pathname && addrURL.pathname !== "/") addrBasePath = addrURL.pathname;
582
+ }
513
583
  let url;
514
584
  let init;
515
585
  if (input instanceof Request) {
@@ -527,43 +597,52 @@ async function proxyFetch(addr, input, inputInit) {
527
597
  ...init
528
598
  };
529
599
  if (init.body) init.duplex = "half";
530
- const path = url.pathname + url.search;
600
+ const requestPath = url.pathname + url.search;
601
+ const path = addrBasePath ? joinURL(addrBasePath, requestPath) : requestPath;
531
602
  const reqHeaders = {};
532
- if (init.headers) {
533
- const h = init.headers instanceof Headers ? init.headers : new Headers(init.headers);
534
- for (const [key, value] of h) reqHeaders[key] = value;
603
+ if (init.headers) if (!(init.headers instanceof Headers) && !Array.isArray(init.headers)) Object.assign(reqHeaders, init.headers);
604
+ else for (const [key, value] of init.headers) {
605
+ const existing = reqHeaders[key];
606
+ if (existing === void 0) reqHeaders[key] = value;
607
+ else reqHeaders[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
535
608
  }
536
- const res = await new Promise((resolve, reject) => {
537
- const reqOpts = {
538
- method: init.method || "GET",
539
- path,
540
- headers: reqHeaders
541
- };
542
- if (resolvedAddr.socketPath) reqOpts.socketPath = resolvedAddr.socketPath;
543
- else {
544
- reqOpts.hostname = resolvedAddr.host || "localhost";
545
- reqOpts.port = resolvedAddr.port;
546
- }
547
- const req = request(reqOpts, resolve);
548
- req.on("error", reject);
549
- if (init.body instanceof ReadableStream) {
550
- const readable = Readable.fromWeb(init.body);
551
- readable.on("error", reject);
552
- readable.pipe(req);
553
- } else if (init.body) req.end(init.body);
554
- else req.end();
609
+ if (opts?.xfwd) {
610
+ if (!reqHeaders["x-forwarded-for"]) reqHeaders["x-forwarded-for"] = url.hostname;
611
+ if (!reqHeaders["x-forwarded-port"]) reqHeaders["x-forwarded-port"] = url.port || (url.protocol === "https:" ? "443" : "80");
612
+ if (!reqHeaders["x-forwarded-proto"]) reqHeaders["x-forwarded-proto"] = url.protocol.replace(":", "");
613
+ if (!reqHeaders["x-forwarded-host"]) reqHeaders["x-forwarded-host"] = url.host;
614
+ }
615
+ if (opts?.changeOrigin) if (resolvedAddr.socketPath) reqHeaders.host = "localhost";
616
+ else {
617
+ const targetHost = resolvedAddr.host || "localhost";
618
+ const targetPort = resolvedAddr.port;
619
+ reqHeaders.host = targetPort && targetPort !== (useHTTPS ? 443 : 80) ? `${targetHost}:${targetPort}` : targetHost;
620
+ }
621
+ const maxRedirects = typeof opts?.followRedirects === "number" ? opts.followRedirects : opts?.followRedirects ? 5 : 0;
622
+ const body = maxRedirects > 0 ? await _bufferBody(init.body) : _toNodeStream(init.body);
623
+ const agent = opts?.agent !== void 0 ? opts.agent || false : useHTTPS ? defaultAgents.https : defaultAgents.http;
624
+ const res = await _sendRequest(useHTTPS ? request$1 : request, init.method || "GET", path, reqHeaders, resolvedAddr, body, {
625
+ signal: init.signal || void 0,
626
+ agent,
627
+ timeout: opts?.timeout,
628
+ ssl: opts?.ssl,
629
+ maxRedirects,
630
+ redirectCount: 0,
631
+ originalHeaders: reqHeaders
555
632
  });
556
- const headers = new Headers();
557
- for (const [key, value] of Object.entries(res.headers)) {
558
- if (key === "transfer-encoding" || key === "keep-alive" || key === "connection") continue;
559
- if (Array.isArray(value)) for (const v of value) headers.append(key, v);
560
- else if (value) headers.set(key, value);
633
+ const resHeaders = [];
634
+ const rawHeaders = res.rawHeaders;
635
+ for (let i = 0; i < rawHeaders.length; i += 2) {
636
+ const key = rawHeaders[i];
637
+ const keyLower = key.toLowerCase();
638
+ if (keyLower === "transfer-encoding" || keyLower === "keep-alive" || keyLower === "connection") continue;
639
+ resHeaders.push([key, rawHeaders[i + 1]]);
561
640
  }
562
641
  const hasBody = res.statusCode !== 204 && res.statusCode !== 304;
563
642
  return new Response(hasBody ? Readable.toWeb(res) : null, {
564
643
  status: res.statusCode,
565
644
  statusText: res.statusMessage,
566
- headers
645
+ headers: resHeaders
567
646
  });
568
647
  }
569
648
  function toInit(init) {
@@ -576,8 +655,98 @@ function toInit(init) {
576
655
  };
577
656
  return init;
578
657
  }
658
+ function _toNodeStream(body) {
659
+ if (!body) return;
660
+ if (typeof body === "string") return Buffer.from(body);
661
+ if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) return Buffer.from(body);
662
+ if (body instanceof ReadableStream) return Readable.fromWeb(body);
663
+ if (body instanceof Blob) return Readable.fromWeb(body.stream());
664
+ return Buffer.from(String(body));
665
+ }
666
+ async function _bufferBody(body) {
667
+ if (!body) return;
668
+ if (typeof body === "string") return Buffer.from(body);
669
+ if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) return Buffer.from(body);
670
+ if (body instanceof ReadableStream) {
671
+ const readable = Readable.fromWeb(body);
672
+ const chunks = [];
673
+ for await (const chunk of readable) chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
674
+ return Buffer.concat(chunks);
675
+ }
676
+ if (body instanceof Blob) return Buffer.from(await body.arrayBuffer());
677
+ return Buffer.from(String(body));
678
+ }
679
+ const _redirectStatuses = new Set([
680
+ 301,
681
+ 302,
682
+ 303,
683
+ 307,
684
+ 308
685
+ ]);
686
+ function _sendRequest(doRequest, method, path, headers, addr, body, opts) {
687
+ return new Promise((resolve, reject) => {
688
+ const reqOpts = {
689
+ method,
690
+ path,
691
+ headers,
692
+ agent: opts.agent
693
+ };
694
+ if (addr.socketPath) reqOpts.socketPath = addr.socketPath;
695
+ else {
696
+ reqOpts.hostname = addr.host || "localhost";
697
+ reqOpts.port = addr.port;
698
+ }
699
+ if (opts.signal) reqOpts.signal = opts.signal;
700
+ if (opts.ssl) Object.assign(reqOpts, opts.ssl);
701
+ const req = doRequest(reqOpts, (res) => {
702
+ const statusCode = res.statusCode;
703
+ if (opts.maxRedirects > 0 && _redirectStatuses.has(statusCode) && opts.redirectCount < opts.maxRedirects && res.headers.location) {
704
+ res.resume();
705
+ const currentURL = new URL(path, `http://${addr.host || "localhost"}:${addr.port || 80}`);
706
+ const location = new URL(res.headers.location, currentURL);
707
+ const redirectHTTPS = isSSL.test(location.protocol);
708
+ const preserveMethod = statusCode === 307 || statusCode === 308;
709
+ const redirectMethod = preserveMethod ? method : "GET";
710
+ const redirectHeaders = { ...opts.originalHeaders };
711
+ redirectHeaders.host = location.host;
712
+ if (location.host !== currentURL.host) {
713
+ delete redirectHeaders.authorization;
714
+ delete redirectHeaders.cookie;
715
+ }
716
+ if (!preserveMethod) {
717
+ delete redirectHeaders["content-length"];
718
+ delete redirectHeaders["content-type"];
719
+ delete redirectHeaders["transfer-encoding"];
720
+ }
721
+ _sendRequest(redirectHTTPS ? request$1 : request, redirectMethod, location.pathname + location.search, redirectHeaders, {
722
+ host: location.hostname,
723
+ port: Number(location.port) || (redirectHTTPS ? 443 : 80)
724
+ }, preserveMethod ? body : void 0, {
725
+ ...opts,
726
+ redirectCount: opts.redirectCount + 1
727
+ }).then(resolve, reject);
728
+ return;
729
+ }
730
+ resolve(res);
731
+ });
732
+ req.on("error", reject);
733
+ if (opts.timeout) req.setTimeout(opts.timeout, () => {
734
+ req.destroy(/* @__PURE__ */ new Error("Proxy request timed out"));
735
+ });
736
+ if (body instanceof Readable) {
737
+ body.on("error", (err) => {
738
+ req.destroy(err);
739
+ reject(err);
740
+ });
741
+ body.pipe(req);
742
+ } else if (body) req.end(body);
743
+ else req.end();
744
+ });
745
+ }
579
746
  function proxyUpgrade(addr, req, socket, head, opts) {
580
747
  const resolvedAddr = parseAddr(addr);
748
+ let useSSL = false;
749
+ if (typeof addr === "string" && !addr.startsWith("unix:")) useSSL = isSSL.test(new URL(addr).protocol);
581
750
  if (req.method !== "GET" || req.headers.upgrade?.toLowerCase() !== "websocket") {
582
751
  socket.destroy();
583
752
  return Promise.reject(/* @__PURE__ */ new Error("Not a valid WebSocket upgrade request"));
@@ -590,7 +759,7 @@ function proxyUpgrade(addr, req, socket, head, opts) {
590
759
  req.headers["x-forwarded-port"] = `${xfPort ? `${xfPort},` : ""}${getPort(req)}`;
591
760
  req.headers["x-forwarded-proto"] = `${xfProto ? `${xfProto},` : ""}${hasEncryptedConnection(req) ? "wss" : "ws"}`;
592
761
  }
593
- const target = _buildTargetURL(resolvedAddr);
762
+ const target = _buildTargetURL(resolvedAddr, useSSL);
594
763
  const requestOptions = {
595
764
  ...opts,
596
765
  target,
@@ -607,8 +776,11 @@ function proxyUpgrade(addr, req, socket, head, opts) {
607
776
  proxyReq.once("error", onOutgoingError);
608
777
  proxyReq.once("response", (res) => {
609
778
  if (!res.upgrade) {
610
- sock.write(_createHttpHeader(`HTTP/${res.httpVersion} ${res.statusCode} ${res.statusMessage}`, res.headers));
611
- res.pipe(sock);
779
+ if (!sock.destroyed && sock.writable) {
780
+ sock.write(_createHttpHeader(`HTTP/${res.httpVersion} ${res.statusCode} ${res.statusMessage}`, res.headers));
781
+ res.on("error", onOutgoingError);
782
+ res.pipe(sock);
783
+ } else res.resume();
612
784
  if (!settled) {
613
785
  settled = true;
614
786
  reject(/* @__PURE__ */ new Error("Upstream server did not upgrade the connection"));
@@ -645,27 +817,23 @@ function proxyUpgrade(addr, req, socket, head, opts) {
645
817
  }
646
818
  });
647
819
  }
648
- function _buildTargetURL(addr) {
820
+ function _buildTargetURL(addr, useSSL = false) {
821
+ const protocol = useSSL ? "https" : "http";
649
822
  if (addr.socketPath) {
650
- const url = new URL("http://unix");
823
+ const url = new URL(`${protocol}://unix`);
651
824
  url.socketPath = addr.socketPath;
652
825
  return url;
653
826
  }
654
- return new URL(`http://${addr.host || "localhost"}${addr.port ? `:${addr.port}` : ""}`);
827
+ return new URL(`${protocol}://${addr.host || "localhost"}${addr.port ? `:${addr.port}` : ""}`);
655
828
  }
656
829
  function _createHttpHeader(line, headers) {
657
830
  let result = line;
658
831
  for (const key of Object.keys(headers)) {
659
832
  const value = headers[key];
660
833
  if (value === void 0) continue;
661
- if (Array.isArray(value)) for (const element of value) result += `\r
662
- ${key}: ${element}`;
663
- else result += `\r
664
- ${key}: ${value}`;
834
+ if (Array.isArray(value)) for (const element of value) result += `\r\n${key}: ${element}`;
835
+ else result += `\r\n${key}: ${value}`;
665
836
  }
666
- return `${result}\r
667
- \r
668
- `;
837
+ return `${result}\r\n\r\n`;
669
838
  }
670
- //#endregion
671
839
  export { proxyFetch as n, proxyUpgrade as r, createProxyServer as t };
@@ -1,4 +1,3 @@
1
- //#region node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
2
1
  function set(obj, key, val) {
3
2
  if (typeof val.value === "object") val.value = klona(val.value);
4
3
  if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") Object.defineProperty(obj, key, val);
@@ -33,5 +32,4 @@ function klona(x) {
33
32
  }
34
33
  return tmp || x;
35
34
  }
36
- //#endregion
37
35
  export { klona as t };