vite-plugin-rpx 0.11.23 → 0.11.24
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.
- package/dist/index.js +215 -20
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22443,6 +22443,151 @@ var init_https = __esm(() => {
|
|
|
22443
22443
|
SHARED_DEV_HOST_CERT_PATH = join12(homedir8(), ".stacks", "ssl", "rpx.localhost.crt");
|
|
22444
22444
|
});
|
|
22445
22445
|
|
|
22446
|
+
// ../rpx/src/load-balancer.ts
|
|
22447
|
+
function resolveHealthCheckConfig(config6) {
|
|
22448
|
+
return {
|
|
22449
|
+
enabled: config6?.enabled ?? false,
|
|
22450
|
+
path: config6?.path ?? DEFAULT_HEALTH_CHECK_PATH,
|
|
22451
|
+
interval: config6?.interval ?? DEFAULT_HEALTH_CHECK_INTERVAL_MS,
|
|
22452
|
+
timeout: config6?.timeout ?? DEFAULT_HEALTH_CHECK_TIMEOUT_MS,
|
|
22453
|
+
healthyThreshold: config6?.healthyThreshold ?? DEFAULT_HEALTHY_THRESHOLD,
|
|
22454
|
+
unhealthyThreshold: config6?.unhealthyThreshold ?? DEFAULT_UNHEALTHY_THRESHOLD
|
|
22455
|
+
};
|
|
22456
|
+
}
|
|
22457
|
+
function normalizeUpstreams(from) {
|
|
22458
|
+
const list = Array.isArray(from) ? from : [from];
|
|
22459
|
+
return list.map((entry) => {
|
|
22460
|
+
const target = typeof entry === "string" ? { url: entry } : entry;
|
|
22461
|
+
return {
|
|
22462
|
+
url: target.url,
|
|
22463
|
+
weight: target.weight && target.weight > 0 ? target.weight : 1,
|
|
22464
|
+
healthy: true,
|
|
22465
|
+
activeConnections: 0,
|
|
22466
|
+
consecutiveFailures: 0,
|
|
22467
|
+
consecutiveSuccesses: 0
|
|
22468
|
+
};
|
|
22469
|
+
});
|
|
22470
|
+
}
|
|
22471
|
+
function primaryUpstreamUrl(from) {
|
|
22472
|
+
if (!from)
|
|
22473
|
+
return "localhost:5173";
|
|
22474
|
+
const first = Array.isArray(from) ? from[0] : from;
|
|
22475
|
+
if (!first)
|
|
22476
|
+
return "localhost:5173";
|
|
22477
|
+
return typeof first === "string" ? first : first.url;
|
|
22478
|
+
}
|
|
22479
|
+
function createUpstreamPool(from, lbConfig) {
|
|
22480
|
+
return {
|
|
22481
|
+
upstreams: normalizeUpstreams(from),
|
|
22482
|
+
strategy: lbConfig?.strategy ?? "round-robin",
|
|
22483
|
+
healthCheck: resolveHealthCheckConfig(lbConfig?.healthCheck),
|
|
22484
|
+
cursor: 0,
|
|
22485
|
+
wrrCurrentWeights: [],
|
|
22486
|
+
healthCheckTimer: null
|
|
22487
|
+
};
|
|
22488
|
+
}
|
|
22489
|
+
function healthyUpstreams(pool) {
|
|
22490
|
+
const healthy = pool.upstreams.filter((u2) => u2.healthy);
|
|
22491
|
+
if (healthy.length === 0 && pool.upstreams.length === 1)
|
|
22492
|
+
return pool.upstreams;
|
|
22493
|
+
return healthy;
|
|
22494
|
+
}
|
|
22495
|
+
function selectRoundRobin(pool, candidates) {
|
|
22496
|
+
const idx = pool.cursor % candidates.length;
|
|
22497
|
+
pool.cursor = (pool.cursor + 1) % candidates.length;
|
|
22498
|
+
return candidates[idx];
|
|
22499
|
+
}
|
|
22500
|
+
function selectWeightedRoundRobin(pool, candidates) {
|
|
22501
|
+
if (pool.wrrCurrentWeights.length !== candidates.length)
|
|
22502
|
+
pool.wrrCurrentWeights = candidates.map(() => 0);
|
|
22503
|
+
const totalWeight = candidates.reduce((sum, u2) => sum + u2.weight, 0);
|
|
22504
|
+
let bestIdx = 0;
|
|
22505
|
+
for (let i2 = 0;i2 < candidates.length; i2++) {
|
|
22506
|
+
pool.wrrCurrentWeights[i2] += candidates[i2].weight;
|
|
22507
|
+
if (pool.wrrCurrentWeights[i2] > pool.wrrCurrentWeights[bestIdx])
|
|
22508
|
+
bestIdx = i2;
|
|
22509
|
+
}
|
|
22510
|
+
pool.wrrCurrentWeights[bestIdx] -= totalWeight;
|
|
22511
|
+
return candidates[bestIdx];
|
|
22512
|
+
}
|
|
22513
|
+
function selectLeastConnections(candidates) {
|
|
22514
|
+
let best = candidates[0];
|
|
22515
|
+
for (let i2 = 1;i2 < candidates.length; i2++) {
|
|
22516
|
+
if (candidates[i2].activeConnections < best.activeConnections)
|
|
22517
|
+
best = candidates[i2];
|
|
22518
|
+
}
|
|
22519
|
+
return best;
|
|
22520
|
+
}
|
|
22521
|
+
function selectUpstream(pool) {
|
|
22522
|
+
const candidates = healthyUpstreams(pool);
|
|
22523
|
+
if (candidates.length === 0)
|
|
22524
|
+
return;
|
|
22525
|
+
if (candidates.length === 1)
|
|
22526
|
+
return candidates[0];
|
|
22527
|
+
switch (pool.strategy) {
|
|
22528
|
+
case "weighted-round-robin":
|
|
22529
|
+
return selectWeightedRoundRobin(pool, candidates);
|
|
22530
|
+
case "least-connections":
|
|
22531
|
+
return selectLeastConnections(candidates);
|
|
22532
|
+
case "round-robin":
|
|
22533
|
+
default:
|
|
22534
|
+
return selectRoundRobin(pool, candidates);
|
|
22535
|
+
}
|
|
22536
|
+
}
|
|
22537
|
+
function markSuccess(pool, upstream) {
|
|
22538
|
+
upstream.consecutiveFailures = 0;
|
|
22539
|
+
upstream.consecutiveSuccesses += 1;
|
|
22540
|
+
if (!upstream.healthy && upstream.consecutiveSuccesses >= pool.healthCheck.healthyThreshold)
|
|
22541
|
+
upstream.healthy = true;
|
|
22542
|
+
}
|
|
22543
|
+
function markFailure(pool, upstream) {
|
|
22544
|
+
upstream.consecutiveSuccesses = 0;
|
|
22545
|
+
upstream.consecutiveFailures += 1;
|
|
22546
|
+
if (upstream.healthy && upstream.consecutiveFailures >= pool.healthCheck.unhealthyThreshold)
|
|
22547
|
+
upstream.healthy = false;
|
|
22548
|
+
}
|
|
22549
|
+
function splitHostPort(hostPort) {
|
|
22550
|
+
const idx = hostPort.lastIndexOf(":");
|
|
22551
|
+
if (idx === -1)
|
|
22552
|
+
return { hostname: hostPort, port: 80 };
|
|
22553
|
+
const port = Number(hostPort.slice(idx + 1));
|
|
22554
|
+
return { hostname: hostPort.slice(0, idx), port: Number.isFinite(port) ? port : 80 };
|
|
22555
|
+
}
|
|
22556
|
+
async function probeUpstream(pool, upstream) {
|
|
22557
|
+
const { hostname, port } = splitHostPort(upstream.url);
|
|
22558
|
+
const controller = new AbortController;
|
|
22559
|
+
const timer = setTimeout(() => controller.abort(), pool.healthCheck.timeout);
|
|
22560
|
+
try {
|
|
22561
|
+
const res = await fetch(`http://${hostname}:${port}${pool.healthCheck.path}`, {
|
|
22562
|
+
signal: controller.signal,
|
|
22563
|
+
redirect: "manual"
|
|
22564
|
+
});
|
|
22565
|
+
res.body?.cancel().catch(() => {});
|
|
22566
|
+
markSuccess(pool, upstream);
|
|
22567
|
+
} catch {
|
|
22568
|
+
markFailure(pool, upstream);
|
|
22569
|
+
} finally {
|
|
22570
|
+
clearTimeout(timer);
|
|
22571
|
+
}
|
|
22572
|
+
}
|
|
22573
|
+
function startHealthChecks(pool) {
|
|
22574
|
+
if (!pool.healthCheck.enabled || pool.healthCheckTimer || pool.upstreams.length < 2)
|
|
22575
|
+
return;
|
|
22576
|
+
const timer = setInterval(() => {
|
|
22577
|
+
for (const upstream of pool.upstreams)
|
|
22578
|
+
probeUpstream(pool, upstream);
|
|
22579
|
+
}, pool.healthCheck.interval);
|
|
22580
|
+
timer.unref?.();
|
|
22581
|
+
pool.healthCheckTimer = timer;
|
|
22582
|
+
}
|
|
22583
|
+
function stopHealthChecks(pool) {
|
|
22584
|
+
if (pool.healthCheckTimer) {
|
|
22585
|
+
clearInterval(pool.healthCheckTimer);
|
|
22586
|
+
pool.healthCheckTimer = null;
|
|
22587
|
+
}
|
|
22588
|
+
}
|
|
22589
|
+
var DEFAULT_HEALTHY_THRESHOLD = 2, DEFAULT_UNHEALTHY_THRESHOLD = 3, DEFAULT_HEALTH_CHECK_PATH = "/", DEFAULT_HEALTH_CHECK_INTERVAL_MS = 1e4, DEFAULT_HEALTH_CHECK_TIMEOUT_MS = 2000;
|
|
22590
|
+
|
|
22446
22591
|
// ../rpx/src/auth.ts
|
|
22447
22592
|
import { createHash, timingSafeEqual } from "node:crypto";
|
|
22448
22593
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -23542,8 +23687,15 @@ function stripBasePath(pathname, basePath) {
|
|
|
23542
23687
|
}
|
|
23543
23688
|
return pathname;
|
|
23544
23689
|
}
|
|
23545
|
-
function
|
|
23546
|
-
|
|
23690
|
+
function pickUpstream(route) {
|
|
23691
|
+
if (route.upstreamPool)
|
|
23692
|
+
return selectUpstream(route.upstreamPool);
|
|
23693
|
+
if (route.sourceHost)
|
|
23694
|
+
return { url: route.sourceHost, weight: 1, healthy: true, activeConnections: 0, consecutiveFailures: 0, consecutiveSuccesses: 0 };
|
|
23695
|
+
return;
|
|
23696
|
+
}
|
|
23697
|
+
function resolveTarget(pathname, route, upstream, verbose) {
|
|
23698
|
+
let targetHost = upstream?.url ?? route.sourceHost ?? "";
|
|
23547
23699
|
const stripBase = route.stripBasePathPrefix ?? false;
|
|
23548
23700
|
let targetPath = stripBase ? stripBasePath(pathname, route.basePath) : pathname;
|
|
23549
23701
|
const rewriteMatch = resolvePathRewrite(targetPath, route.pathRewrites);
|
|
@@ -23598,9 +23750,10 @@ function createProxyFetchHandler(getRoute, verbose, onNoRoute) {
|
|
|
23598
23750
|
return serveStaticFile(staticPath, route.static);
|
|
23599
23751
|
}
|
|
23600
23752
|
if (req.headers.get("upgrade")?.toLowerCase() === "websocket") {
|
|
23601
|
-
|
|
23753
|
+
const wsUpstream = pickUpstream(route);
|
|
23754
|
+
if (!server || !wsUpstream)
|
|
23602
23755
|
return new Response("WebSocket upgrade not supported here", { status: 400 });
|
|
23603
|
-
const { targetHost: targetHost2, targetPath: targetPath2 } = resolveTarget(pathname, route, verbose);
|
|
23756
|
+
const { targetHost: targetHost2, targetPath: targetPath2 } = resolveTarget(pathname, route, wsUpstream, verbose);
|
|
23604
23757
|
const targetUrl = `ws://${targetHost2}${targetPath2}${search}`;
|
|
23605
23758
|
const forwardHeaders = {};
|
|
23606
23759
|
for (const [k2, v2] of req.headers) {
|
|
@@ -23619,8 +23772,10 @@ function createProxyFetchHandler(getRoute, verbose, onNoRoute) {
|
|
|
23619
23772
|
}
|
|
23620
23773
|
return new Response("WebSocket upgrade failed", { status: 400 });
|
|
23621
23774
|
}
|
|
23622
|
-
|
|
23775
|
+
const upstream = pickUpstream(route);
|
|
23776
|
+
if (!upstream) {
|
|
23623
23777
|
return new Response(`No upstream configured for ${hostname}`, { status: 502 });
|
|
23778
|
+
}
|
|
23624
23779
|
if (route.cleanUrls && pathname.endsWith(".html")) {
|
|
23625
23780
|
const cleanPath = pathname.replace(/\.html$/, "");
|
|
23626
23781
|
return new Response(null, {
|
|
@@ -23628,11 +23783,14 @@ function createProxyFetchHandler(getRoute, verbose, onNoRoute) {
|
|
|
23628
23783
|
headers: { Location: cleanPath }
|
|
23629
23784
|
});
|
|
23630
23785
|
}
|
|
23631
|
-
const { targetHost, targetPath } = resolveTarget(pathname, route, verbose);
|
|
23632
|
-
const originOverride = route.changeOrigin ? `http://${
|
|
23786
|
+
const { targetHost, targetPath } = resolveTarget(pathname, route, upstream, verbose);
|
|
23787
|
+
const originOverride = route.changeOrigin ? `http://${targetHost}` : undefined;
|
|
23633
23788
|
const hasBody = req.body != null && req.method !== "GET" && req.method !== "HEAD";
|
|
23789
|
+
const pool = route.upstreamPool;
|
|
23790
|
+
if (pool)
|
|
23791
|
+
upstream.activeConnections++;
|
|
23634
23792
|
try {
|
|
23635
|
-
|
|
23793
|
+
const res = await proxyViaPool({
|
|
23636
23794
|
hostPort: targetHost,
|
|
23637
23795
|
method: req.method,
|
|
23638
23796
|
path: `${targetPath}${search}`,
|
|
@@ -23641,9 +23799,14 @@ function createProxyFetchHandler(getRoute, verbose, onNoRoute) {
|
|
|
23641
23799
|
originOverride,
|
|
23642
23800
|
body: req.body
|
|
23643
23801
|
});
|
|
23802
|
+
if (pool)
|
|
23803
|
+
markSuccess(pool, upstream);
|
|
23804
|
+
return res;
|
|
23644
23805
|
} catch (err) {
|
|
23645
23806
|
if (err === TIMEOUT) {
|
|
23646
23807
|
debugLog("request", `Upstream timeout for ${hostname}`, verbose);
|
|
23808
|
+
if (pool)
|
|
23809
|
+
markFailure(pool, upstream);
|
|
23647
23810
|
return new Response("Gateway Timeout", { status: 504 });
|
|
23648
23811
|
}
|
|
23649
23812
|
if (err === POOL_BUSY) {
|
|
@@ -23659,19 +23822,29 @@ function createProxyFetchHandler(getRoute, verbose, onNoRoute) {
|
|
|
23659
23822
|
headers.set("x-forwarded-host", hostname);
|
|
23660
23823
|
if (originOverride !== undefined)
|
|
23661
23824
|
headers.set("origin", originOverride);
|
|
23662
|
-
|
|
23825
|
+
const res = await fetch(`http://${targetHost}${targetPath}${search}`, {
|
|
23663
23826
|
method: req.method,
|
|
23664
23827
|
headers,
|
|
23665
23828
|
body: req.body,
|
|
23666
23829
|
redirect: "manual"
|
|
23667
23830
|
});
|
|
23831
|
+
if (pool)
|
|
23832
|
+
markSuccess(pool, upstream);
|
|
23833
|
+
return res;
|
|
23668
23834
|
} catch (fetchErr) {
|
|
23669
23835
|
debugLog("request", `Proxy error for ${hostname}: ${fetchErr}`, verbose);
|
|
23836
|
+
if (pool)
|
|
23837
|
+
markFailure(pool, upstream);
|
|
23670
23838
|
return new Response(`Proxy Error: ${fetchErr}`, { status: 502 });
|
|
23671
23839
|
}
|
|
23672
23840
|
}
|
|
23673
23841
|
debugLog("request", `Proxy error for ${hostname}: ${err}`, verbose);
|
|
23842
|
+
if (pool)
|
|
23843
|
+
markFailure(pool, upstream);
|
|
23674
23844
|
return new Response(`Proxy Error: ${err}`, { status: 502 });
|
|
23845
|
+
} finally {
|
|
23846
|
+
if (pool)
|
|
23847
|
+
upstream.activeConnections--;
|
|
23675
23848
|
}
|
|
23676
23849
|
};
|
|
23677
23850
|
return async (req, server) => {
|
|
@@ -24278,7 +24451,7 @@ function isValidEntry(value) {
|
|
|
24278
24451
|
return false;
|
|
24279
24452
|
const e = value;
|
|
24280
24453
|
const pidOk = e.pid === undefined || typeof e.pid === "number" && Number.isInteger(e.pid) && e.pid > 0;
|
|
24281
|
-
const hasFrom = typeof e.from === "string" && e.from.length > 0;
|
|
24454
|
+
const hasFrom = typeof e.from === "string" && e.from.length > 0 || Array.isArray(e.from) && e.from.length > 0;
|
|
24282
24455
|
const hasStatic = typeof e.static === "string" || !!e.static && typeof e.static === "object" && typeof e.static.dir === "string";
|
|
24283
24456
|
const pathOk = e.path === undefined || typeof e.path === "string";
|
|
24284
24457
|
return typeof e.id === "string" && isValidId(e.id) && (hasFrom || hasStatic) && typeof e.to === "string" && e.to.length > 0 && pathOk && pidOk && typeof e.createdAt === "string";
|
|
@@ -25310,6 +25483,7 @@ async function ensureDaemonRunning(opts = {}) {
|
|
|
25310
25483
|
throw spawnError;
|
|
25311
25484
|
throw new Error(`rpx daemon failed to start within ${timeoutMs}ms (rpxDir=${rpxDir})`);
|
|
25312
25485
|
}
|
|
25486
|
+
var registryUpstreamPools;
|
|
25313
25487
|
var init_daemon = __esm(() => {
|
|
25314
25488
|
init_logger();
|
|
25315
25489
|
init_https();
|
|
@@ -25325,6 +25499,7 @@ var init_daemon = __esm(() => {
|
|
|
25325
25499
|
init_registry();
|
|
25326
25500
|
init_dns();
|
|
25327
25501
|
init_utils();
|
|
25502
|
+
registryUpstreamPools = new Map;
|
|
25328
25503
|
});
|
|
25329
25504
|
|
|
25330
25505
|
// src/index.ts
|
|
@@ -25392,7 +25567,8 @@ async function runViaDaemon(opts) {
|
|
|
25392
25567
|
cleanUrls: p2.cleanUrls,
|
|
25393
25568
|
changeOrigin: p2.changeOrigin,
|
|
25394
25569
|
pathRewrites: p2.pathRewrites,
|
|
25395
|
-
static: p2.static
|
|
25570
|
+
static: p2.static,
|
|
25571
|
+
loadBalancer: p2.loadBalancer
|
|
25396
25572
|
}, registryDir, verbose);
|
|
25397
25573
|
}
|
|
25398
25574
|
const result = await ensureDaemonRunning({
|
|
@@ -25834,6 +26010,7 @@ var processManager2 = new ProcessManager;
|
|
|
25834
26010
|
var version3 = "0.12.0";
|
|
25835
26011
|
var globalPortManager = new DefaultPortManager("0.0.0.0");
|
|
25836
26012
|
var activeServers = new Set;
|
|
26013
|
+
var activeUpstreamPools = new Set;
|
|
25837
26014
|
var isCleaningUp = false;
|
|
25838
26015
|
var cleanupPromiseResolve = null;
|
|
25839
26016
|
var cleanupPromise = null;
|
|
@@ -25873,6 +26050,9 @@ async function cleanup(options) {
|
|
|
25873
26050
|
}));
|
|
25874
26051
|
cleanupPromises.push(...serverClosePromises);
|
|
25875
26052
|
activeServers.clear();
|
|
26053
|
+
for (const pool of activeUpstreamPools)
|
|
26054
|
+
stopHealthChecks(pool);
|
|
26055
|
+
activeUpstreamPools.clear();
|
|
25876
26056
|
if (options?.hosts && options.domains?.length) {
|
|
25877
26057
|
debugLog("cleanup", "Cleaning up hosts file entries", options?.verbose);
|
|
25878
26058
|
debugLog("cleanup", `Original domains for cleanup: ${JSON.stringify(options.domains)}`, options?.verbose);
|
|
@@ -26030,7 +26210,8 @@ async function testConnection(hostname, port, verbose, retries = 5) {
|
|
|
26030
26210
|
}
|
|
26031
26211
|
async function startServer(options) {
|
|
26032
26212
|
debugLog("server", `Starting server with options: ${safeStringify(options)}`, options.verbose);
|
|
26033
|
-
const
|
|
26213
|
+
const primaryFrom = primaryUpstreamUrl(options.from);
|
|
26214
|
+
const fromUrl = new URL(primaryFrom.startsWith("http") ? primaryFrom : `http://${primaryFrom}`);
|
|
26034
26215
|
const toUrl = new URL((options.to?.startsWith("http") ? options.to : `http://${options.to}`) || "rpx.localhost");
|
|
26035
26216
|
const fromPort = Number.parseInt(fromUrl.port) || (fromUrl.protocol.includes("https:") ? 443 : 80);
|
|
26036
26217
|
const hostsToCheck = [toUrl.hostname];
|
|
@@ -26111,7 +26292,8 @@ async function startServer(options) {
|
|
|
26111
26292
|
debugLog("server", `Setting up reverse proxy with SSL config for ${toUrl.hostname}`, options.verbose);
|
|
26112
26293
|
await setupProxy({
|
|
26113
26294
|
...options,
|
|
26114
|
-
from:
|
|
26295
|
+
from: primaryFrom,
|
|
26296
|
+
originalFrom: options.from || primaryFrom,
|
|
26115
26297
|
to: toUrl.hostname,
|
|
26116
26298
|
fromPort,
|
|
26117
26299
|
sourceUrl: {
|
|
@@ -26121,12 +26303,15 @@ async function startServer(options) {
|
|
|
26121
26303
|
ssl: sslConfig
|
|
26122
26304
|
});
|
|
26123
26305
|
}
|
|
26124
|
-
async function createProxyServer(from, to, listenPort, sourceUrl, ssl, vitePluginUsage, verbose, cleanUrls, changeOrigin, auth) {
|
|
26306
|
+
async function createProxyServer(from, to, listenPort, sourceUrl, ssl, vitePluginUsage, verbose, cleanUrls, changeOrigin, auth, originalFrom, loadBalancer) {
|
|
26125
26307
|
debugLog("proxy", `Creating proxy server ${from} -> ${to} with cleanUrls: ${cleanUrls}`, verbose);
|
|
26308
|
+
const pool = createUpstreamPool(originalFrom ?? sourceUrl.host, loadBalancer);
|
|
26309
|
+
startHealthChecks(pool);
|
|
26126
26310
|
const routeEntries = [{
|
|
26127
26311
|
host: to,
|
|
26128
26312
|
route: {
|
|
26129
26313
|
sourceHost: sourceUrl.host,
|
|
26314
|
+
upstreamPool: pool,
|
|
26130
26315
|
cleanUrls: cleanUrls || false,
|
|
26131
26316
|
changeOrigin: changeOrigin || false,
|
|
26132
26317
|
basePath: "/",
|
|
@@ -26134,8 +26319,11 @@ async function createProxyServer(from, to, listenPort, sourceUrl, ssl, vitePlugi
|
|
|
26134
26319
|
}
|
|
26135
26320
|
}];
|
|
26136
26321
|
const server = createSharedProxyServer({ routeEntries, listenPort, sslConfig: ssl, originGuard: null, verbose: verbose ?? false });
|
|
26137
|
-
if (!server)
|
|
26322
|
+
if (!server) {
|
|
26323
|
+
stopHealthChecks(pool);
|
|
26138
26324
|
throw new Error(`Failed to start proxy server for ${to} on port ${listenPort}`);
|
|
26325
|
+
}
|
|
26326
|
+
activeUpstreamPools.add(pool);
|
|
26139
26327
|
logToConsole({
|
|
26140
26328
|
from,
|
|
26141
26329
|
to,
|
|
@@ -26148,7 +26336,7 @@ async function createProxyServer(from, to, listenPort, sourceUrl, ssl, vitePlugi
|
|
|
26148
26336
|
}
|
|
26149
26337
|
async function setupProxy(options) {
|
|
26150
26338
|
debugLog("setup", `Setting up reverse proxy: ${safeStringify(options)}`, options.verbose);
|
|
26151
|
-
const { from, to, sourceUrl, ssl, verbose, cleanup: cleanupOptions, vitePluginUsage, changeOrigin, cleanUrls } = options;
|
|
26339
|
+
const { from, originalFrom, to, sourceUrl, ssl, verbose, cleanup: cleanupOptions, vitePluginUsage, changeOrigin, cleanUrls } = options;
|
|
26152
26340
|
const httpPort = 80;
|
|
26153
26341
|
const httpsPort = 443;
|
|
26154
26342
|
const hostname = "0.0.0.0";
|
|
@@ -26215,7 +26403,7 @@ async function setupProxy(options) {
|
|
|
26215
26403
|
portManager2.usedPorts.add(finalPort);
|
|
26216
26404
|
debugLog("setup", `Using standard ${targetPort === 443 ? "HTTPS" : "HTTP"} port ${targetPort} for ${to}`, verbose);
|
|
26217
26405
|
}
|
|
26218
|
-
await createProxyServer(from, to, finalPort, sourceUrl, ssl, vitePluginUsage, verbose, cleanUrls, changeOrigin, resolveAuth(options.auth));
|
|
26406
|
+
await createProxyServer(from, to, finalPort, sourceUrl, ssl, vitePluginUsage, verbose, cleanUrls, changeOrigin, resolveAuth(options.auth), originalFrom, options.loadBalancer);
|
|
26219
26407
|
} catch (err) {
|
|
26220
26408
|
debugLog("setup", `Setup failed: ${err}`, verbose);
|
|
26221
26409
|
log.error(`Failed to setup reverse proxy: ${err.message}`);
|
|
@@ -26323,7 +26511,8 @@ async function startProxies(options) {
|
|
|
26323
26511
|
debugLog("watch", `Starting command for ${proxyId} with command: ${proxy.start.command}`, verbose);
|
|
26324
26512
|
log.info(`Starting command for ${proxyId}...`);
|
|
26325
26513
|
await processManager2.startProcess(proxyId, proxy.start, verbose);
|
|
26326
|
-
const
|
|
26514
|
+
const proxyPrimaryFrom = primaryUpstreamUrl(proxy.from);
|
|
26515
|
+
const fromUrl = new URL(proxyPrimaryFrom.startsWith("http") ? proxyPrimaryFrom : `http://${proxyPrimaryFrom}`);
|
|
26327
26516
|
const hostname = fromUrl.hostname || "localhost";
|
|
26328
26517
|
const port = Number(fromUrl.port) || 80;
|
|
26329
26518
|
try {
|
|
@@ -26349,7 +26538,8 @@ async function startProxies(options) {
|
|
|
26349
26538
|
debugLog("watch", `Starting command: ${mergedOptions.start.command}`, verbose);
|
|
26350
26539
|
await processManager2.startProcess(proxyId, mergedOptions.start, verbose);
|
|
26351
26540
|
}
|
|
26352
|
-
const
|
|
26541
|
+
const mergedPrimaryFrom = primaryUpstreamUrl(mergedOptions.from);
|
|
26542
|
+
const fromUrl = new URL(mergedPrimaryFrom.startsWith("http") ? mergedPrimaryFrom : `http://${mergedPrimaryFrom}`);
|
|
26353
26543
|
const hostname = fromUrl.hostname || "localhost";
|
|
26354
26544
|
const port = Number(fromUrl.port) || 80;
|
|
26355
26545
|
try {
|
|
@@ -26559,12 +26749,17 @@ async function collectRouteEntries(proxyOptions, hostsEnabled, verbose) {
|
|
|
26559
26749
|
});
|
|
26560
26750
|
debugLog("proxies", `Route: ${domain}${routePath ?? ""} → static ${typeof option.static === "string" ? option.static : option.static.dir}${auth ? " (auth)" : ""}`, verbose);
|
|
26561
26751
|
} else {
|
|
26562
|
-
const
|
|
26752
|
+
const primaryFrom = primaryUpstreamUrl(option.from);
|
|
26753
|
+
const fromUrl = new URL(primaryFrom.startsWith("http") ? primaryFrom : `http://${primaryFrom}`);
|
|
26754
|
+
const pool = createUpstreamPool(option.from ?? fromUrl.host, option.loadBalancer);
|
|
26755
|
+
startHealthChecks(pool);
|
|
26756
|
+
activeUpstreamPools.add(pool);
|
|
26563
26757
|
routeEntries.push({
|
|
26564
26758
|
host: domain,
|
|
26565
26759
|
path: routePath,
|
|
26566
26760
|
route: {
|
|
26567
26761
|
sourceHost: fromUrl.host,
|
|
26762
|
+
upstreamPool: pool,
|
|
26568
26763
|
cleanUrls,
|
|
26569
26764
|
changeOrigin: option.changeOrigin || false,
|
|
26570
26765
|
pathRewrites: option.pathRewrites,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-rpx",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.24",
|
|
5
5
|
"description": "A modern and smart reverse proxy. Vite plugin.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"typecheck": "bunx tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@stacksjs/rpx": "0.11.
|
|
50
|
+
"@stacksjs/rpx": "0.11.24",
|
|
51
51
|
"@stacksjs/tlsx": "^0.13.9"
|
|
52
52
|
},
|
|
53
53
|
"simple-git-hooks": {
|