unplugin-https-reverse-proxy 4.0.1 → 4.0.3
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/{chunk-QURDG7SD.js → chunk-MD5CVZP7.js} +187 -20
- package/dist/esbuild.cjs +187 -20
- package/dist/esbuild.js +1 -1
- package/dist/index.cjs +187 -20
- package/dist/index.js +1 -1
- package/dist/nuxt.cjs +187 -20
- package/dist/nuxt.js +1 -1
- package/dist/rollup.cjs +187 -20
- package/dist/rollup.js +1 -1
- package/dist/rspack.cjs +187 -20
- package/dist/rspack.js +1 -1
- package/dist/vite.cjs +187 -20
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +187 -20
- package/dist/webpack.js +1 -1
- package/package.json +1 -1
- package/src/caddy/caddyfile.ts +1 -1
- package/src/caddy/index.ts +110 -21
- package/src/caddy/log.ts +16 -0
- package/src/caddy/tls-health.ts +142 -0
package/dist/index.cjs
CHANGED
|
@@ -13455,7 +13455,7 @@ function validateTemplateContext(ctx) {
|
|
|
13455
13455
|
}
|
|
13456
13456
|
var caddyTemplate = `{
|
|
13457
13457
|
debug
|
|
13458
|
-
auto_https disable_redirects
|
|
13458
|
+
auto_https disable_redirects ignore_loaded_certs
|
|
13459
13459
|
}
|
|
13460
13460
|
|
|
13461
13461
|
:7601 {
|
|
@@ -13722,6 +13722,97 @@ function useCaddyConfig() {
|
|
|
13722
13722
|
};
|
|
13723
13723
|
}
|
|
13724
13724
|
|
|
13725
|
+
// src/caddy/log.ts
|
|
13726
|
+
function isCaddyReloadCancellation(line) {
|
|
13727
|
+
try {
|
|
13728
|
+
const entry = JSON.parse(line);
|
|
13729
|
+
return entry.logger === "tls" && typeof entry.error === "string" && entry.error.endsWith("context canceled");
|
|
13730
|
+
} catch {
|
|
13731
|
+
return false;
|
|
13732
|
+
}
|
|
13733
|
+
}
|
|
13734
|
+
|
|
13735
|
+
// src/caddy/tls-health.ts
|
|
13736
|
+
var import_node_tls = require("tls");
|
|
13737
|
+
function assessTlsCertificate(certificate, hostname, now = Date.now(), verifyHostname = import_node_tls.checkServerIdentity) {
|
|
13738
|
+
if (!certificate.valid_to)
|
|
13739
|
+
return { healthy: false, reason: "certificate_missing" };
|
|
13740
|
+
const expiresAt = new Date(certificate.valid_to);
|
|
13741
|
+
if (Number.isNaN(expiresAt.getTime()))
|
|
13742
|
+
return { healthy: false, reason: "certificate_invalid" };
|
|
13743
|
+
if (expiresAt.getTime() <= now)
|
|
13744
|
+
return { healthy: false, reason: "certificate_expired", expiresAt };
|
|
13745
|
+
try {
|
|
13746
|
+
if (verifyHostname(hostname, certificate))
|
|
13747
|
+
return { healthy: false, reason: "hostname_mismatch" };
|
|
13748
|
+
} catch {
|
|
13749
|
+
return { healthy: false, reason: "certificate_invalid" };
|
|
13750
|
+
}
|
|
13751
|
+
return { healthy: true, expiresAt };
|
|
13752
|
+
}
|
|
13753
|
+
function probeLocalTls(hostname, options = {}) {
|
|
13754
|
+
const {
|
|
13755
|
+
connect: openTlsConnection = import_node_tls.connect,
|
|
13756
|
+
port = 443,
|
|
13757
|
+
timeoutMs = 1e3
|
|
13758
|
+
} = options;
|
|
13759
|
+
return new Promise((resolve2) => {
|
|
13760
|
+
let settled = false;
|
|
13761
|
+
let timeout;
|
|
13762
|
+
const socket = openTlsConnection({
|
|
13763
|
+
host: "127.0.0.1",
|
|
13764
|
+
port,
|
|
13765
|
+
servername: hostname,
|
|
13766
|
+
rejectUnauthorized: false
|
|
13767
|
+
});
|
|
13768
|
+
const finish = (result) => {
|
|
13769
|
+
if (settled)
|
|
13770
|
+
return;
|
|
13771
|
+
settled = true;
|
|
13772
|
+
if (timeout)
|
|
13773
|
+
clearTimeout(timeout);
|
|
13774
|
+
socket.destroy();
|
|
13775
|
+
resolve2(result);
|
|
13776
|
+
};
|
|
13777
|
+
timeout = setTimeout(() => {
|
|
13778
|
+
finish({ healthy: false, reason: "connection_failed" });
|
|
13779
|
+
}, timeoutMs);
|
|
13780
|
+
socket.once("secureConnect", () => {
|
|
13781
|
+
finish(assessTlsCertificate(socket.getPeerCertificate(), hostname));
|
|
13782
|
+
});
|
|
13783
|
+
socket.once("error", () => {
|
|
13784
|
+
finish({ healthy: false, reason: "connection_failed" });
|
|
13785
|
+
});
|
|
13786
|
+
});
|
|
13787
|
+
}
|
|
13788
|
+
function sleep(ms) {
|
|
13789
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
13790
|
+
}
|
|
13791
|
+
async function waitForLocalTls(hostname, options = {}) {
|
|
13792
|
+
const {
|
|
13793
|
+
probe: checkTls = probeLocalTls,
|
|
13794
|
+
retryIntervalMs = 250,
|
|
13795
|
+
retryWindowMs = 3e4,
|
|
13796
|
+
sleep: wait = sleep,
|
|
13797
|
+
...probeOptions
|
|
13798
|
+
} = options;
|
|
13799
|
+
const deadline = Date.now() + retryWindowMs;
|
|
13800
|
+
let result = { healthy: false, reason: "connection_failed" };
|
|
13801
|
+
do {
|
|
13802
|
+
result = await checkTls(hostname, probeOptions);
|
|
13803
|
+
if (result.healthy)
|
|
13804
|
+
return result;
|
|
13805
|
+
const remaining = deadline - Date.now();
|
|
13806
|
+
if (remaining > 0)
|
|
13807
|
+
await wait(Math.min(retryIntervalMs, remaining));
|
|
13808
|
+
} while (Date.now() < deadline);
|
|
13809
|
+
return result;
|
|
13810
|
+
}
|
|
13811
|
+
function formatTlsHealthFailure(hostname, result) {
|
|
13812
|
+
const reason = result.reason === "certificate_expired" && result.expiresAt ? `the certificate expired at ${result.expiresAt.toISOString()}` : result.reason.replaceAll("_", " ");
|
|
13813
|
+
return `[unplugin-https-reverse-proxy] Caddy cannot serve valid HTTPS for ${hostname}: ${reason}. Restart Caddy to retry its automatic certificate renewal. Do not remove Caddy PKI data automatically because that replaces the trusted local root certificate.`;
|
|
13814
|
+
}
|
|
13815
|
+
|
|
13725
13816
|
// src/caddy/utils.ts
|
|
13726
13817
|
var import_node_child_process3 = require("child_process");
|
|
13727
13818
|
var import_node_net = require("net");
|
|
@@ -13859,6 +13950,17 @@ function getCaddyConfig() {
|
|
|
13859
13950
|
}
|
|
13860
13951
|
return caddyConfig;
|
|
13861
13952
|
}
|
|
13953
|
+
function splitHostPort(addr) {
|
|
13954
|
+
const lastColon = addr.lastIndexOf(":");
|
|
13955
|
+
if (lastColon === -1)
|
|
13956
|
+
return { host: addr, port: "" };
|
|
13957
|
+
if (addr.startsWith("[")) {
|
|
13958
|
+
const end = addr.indexOf("]");
|
|
13959
|
+
if (end !== -1 && addr[end + 1] === ":")
|
|
13960
|
+
return { host: addr.slice(1, end), port: addr.slice(end + 2) };
|
|
13961
|
+
}
|
|
13962
|
+
return { host: addr.slice(0, lastColon), port: addr.slice(lastColon + 1) };
|
|
13963
|
+
}
|
|
13862
13964
|
var CaddyInstant = class {
|
|
13863
13965
|
constructor() {
|
|
13864
13966
|
this.inited = false;
|
|
@@ -13900,12 +14002,46 @@ var CaddyInstant = class {
|
|
|
13900
14002
|
await download();
|
|
13901
14003
|
this.inited = true;
|
|
13902
14004
|
}
|
|
14005
|
+
async ensureTlsReady(targetHost) {
|
|
14006
|
+
const health = await waitForLocalTls(targetHost);
|
|
14007
|
+
if (!health.healthy)
|
|
14008
|
+
throw new Error(formatTlsHealthFailure(targetHost, health));
|
|
14009
|
+
}
|
|
14010
|
+
async updateCaddyfile() {
|
|
14011
|
+
const { configJsonRef } = getCaddyConfig();
|
|
14012
|
+
const proxies = Object.values(configJsonRef() || {});
|
|
14013
|
+
const ctx = validateTemplateContext({
|
|
14014
|
+
caddy_root: this.caddyRoot,
|
|
14015
|
+
proxies
|
|
14016
|
+
});
|
|
14017
|
+
this.caddyfile = await genCaddyfile(ctx);
|
|
14018
|
+
await this.writeCaddyfile();
|
|
14019
|
+
}
|
|
14020
|
+
async stopCaddy() {
|
|
14021
|
+
var _a4;
|
|
14022
|
+
try {
|
|
14023
|
+
await import_got_cjs.got.post("http://127.0.0.1:2019/stop", {
|
|
14024
|
+
headers: {
|
|
14025
|
+
Origin: "http://localhost:2019"
|
|
14026
|
+
},
|
|
14027
|
+
retry: {
|
|
14028
|
+
limit: 0
|
|
14029
|
+
},
|
|
14030
|
+
timeout: {
|
|
14031
|
+
request: 2e3
|
|
14032
|
+
}
|
|
14033
|
+
});
|
|
14034
|
+
} catch {
|
|
14035
|
+
}
|
|
14036
|
+
(_a4 = this._caddyChild) == null ? void 0 : _a4.kill();
|
|
14037
|
+
}
|
|
13903
14038
|
/**
|
|
13904
14039
|
* @param source like `127.0.0.1:8080`
|
|
13905
14040
|
* @param target like `test.abc.com`. And if you provide a port ,it will be ignore.
|
|
13906
14041
|
*/
|
|
13907
14042
|
async run(source, target, options) {
|
|
13908
14043
|
source = source.replace("0.0.0.0", "127.0.0.1");
|
|
14044
|
+
source = source.replace(/^localhost(?=:)/i, "127.0.0.1");
|
|
13909
14045
|
const {
|
|
13910
14046
|
restore = true,
|
|
13911
14047
|
base = "/",
|
|
@@ -13917,10 +14053,11 @@ var CaddyInstant = class {
|
|
|
13917
14053
|
this._target = target;
|
|
13918
14054
|
if (!this.inited)
|
|
13919
14055
|
await this.init();
|
|
13920
|
-
|
|
14056
|
+
const sourceHost = splitHostPort(source).host;
|
|
14057
|
+
const targetHost = splitHostPort(target).host;
|
|
14058
|
+
if (!await addHost(sourceHost, targetHost))
|
|
13921
14059
|
throw new Error("update host failed");
|
|
13922
14060
|
consola.success("update host success\n");
|
|
13923
|
-
const targetHost = target.split(":")[0];
|
|
13924
14061
|
const normalizeBase = (b) => {
|
|
13925
14062
|
let out = b || "/";
|
|
13926
14063
|
if (!out.startsWith("/"))
|
|
@@ -13942,16 +14079,16 @@ var CaddyInstant = class {
|
|
|
13942
14079
|
];
|
|
13943
14080
|
const { writeCaddyConfig } = getCaddyConfig();
|
|
13944
14081
|
writeCaddyConfig(proxies);
|
|
14082
|
+
await this.updateCaddyfile();
|
|
14083
|
+
let skipInitialCaddyfileEffect = true;
|
|
13945
14084
|
this._stopEffects.push(
|
|
13946
|
-
effect(
|
|
13947
|
-
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
this.caddyfile = await genCaddyfile(ctx);
|
|
13954
|
-
await this.writeCaddyfile();
|
|
14085
|
+
effect(() => {
|
|
14086
|
+
getCaddyConfig().configJsonRef();
|
|
14087
|
+
if (skipInitialCaddyfileEffect) {
|
|
14088
|
+
skipInitialCaddyfileEffect = false;
|
|
14089
|
+
return;
|
|
14090
|
+
}
|
|
14091
|
+
void this.updateCaddyfile();
|
|
13955
14092
|
})
|
|
13956
14093
|
);
|
|
13957
14094
|
if (!(0, import_node_fs3.existsSync)(caddyLockFilePath))
|
|
@@ -13964,6 +14101,21 @@ var CaddyInstant = class {
|
|
|
13964
14101
|
}
|
|
13965
14102
|
return new Promise((resolve2, reject2) => {
|
|
13966
14103
|
var _a4, _b3;
|
|
14104
|
+
let startupCheckStarted = false;
|
|
14105
|
+
const resolveWhenReady = async () => {
|
|
14106
|
+
if (startupCheckStarted)
|
|
14107
|
+
return;
|
|
14108
|
+
startupCheckStarted = true;
|
|
14109
|
+
try {
|
|
14110
|
+
if (https)
|
|
14111
|
+
await this.ensureTlsReady(targetHost);
|
|
14112
|
+
resolve2();
|
|
14113
|
+
} catch (error) {
|
|
14114
|
+
if (!this.locked)
|
|
14115
|
+
await this.baseCleanup(restore);
|
|
14116
|
+
reject2(error);
|
|
14117
|
+
}
|
|
14118
|
+
};
|
|
13967
14119
|
const setupCleanup = () => {
|
|
13968
14120
|
import_node_process4.default.on("SIGINT", async () => {
|
|
13969
14121
|
if (this.stoped)
|
|
@@ -13980,7 +14132,7 @@ var CaddyInstant = class {
|
|
|
13980
14132
|
});
|
|
13981
14133
|
const originalExit = import_node_process4.default.exit.bind(import_node_process4.default);
|
|
13982
14134
|
import_node_process4.default.exit = async (code) => {
|
|
13983
|
-
const port = Number(source.
|
|
14135
|
+
const port = Number(splitHostPort(source).port);
|
|
13984
14136
|
if (!Number.isNaN(port) && await tryPort(port))
|
|
13985
14137
|
await kill(port);
|
|
13986
14138
|
const pwd = import_node_process4.default.cwd();
|
|
@@ -13988,6 +14140,10 @@ var CaddyInstant = class {
|
|
|
13988
14140
|
if ((0, import_node_fs3.existsSync)(viteCacheDir))
|
|
13989
14141
|
await chmodRecursive(viteCacheDir, 511).catch(() => {
|
|
13990
14142
|
});
|
|
14143
|
+
const viteTempCacheDir = `${pwd}/node_modules/.vite-temp`;
|
|
14144
|
+
if ((0, import_node_fs3.existsSync)(viteTempCacheDir))
|
|
14145
|
+
await chmodRecursive(viteTempCacheDir, 511).catch(() => {
|
|
14146
|
+
});
|
|
13991
14147
|
const nuxtCacheDir = `${pwd}/.nuxt`;
|
|
13992
14148
|
if ((0, import_node_fs3.existsSync)(nuxtCacheDir))
|
|
13993
14149
|
await chmodRecursive(nuxtCacheDir, 511).catch(() => {
|
|
@@ -14019,6 +14175,10 @@ var CaddyInstant = class {
|
|
|
14019
14175
|
const lines = data.toString().split("\n").map((line) => line.trim());
|
|
14020
14176
|
for (const line of lines) {
|
|
14021
14177
|
showCaddyLog && line && console.info(line);
|
|
14178
|
+
if (isCaddyReloadCancellation(line)) {
|
|
14179
|
+
consola.info("Caddy restarted before TLS issuance completed; retrying.\n");
|
|
14180
|
+
continue;
|
|
14181
|
+
}
|
|
14022
14182
|
try {
|
|
14023
14183
|
if (line.includes("Error:") || line && JSON.parse(line).level === "error") {
|
|
14024
14184
|
if (line.includes("parsing caddyfile tokens")) {
|
|
@@ -14039,27 +14199,34 @@ ${line}
|
|
|
14039
14199
|
if (line.includes("config file changed"))
|
|
14040
14200
|
consola.success("Detect added a new reverse proxy config, restarted.\n");
|
|
14041
14201
|
if (line.includes("caddy proxying") || line.includes("serving initial"))
|
|
14042
|
-
|
|
14202
|
+
void resolveWhenReady();
|
|
14043
14203
|
}
|
|
14044
14204
|
});
|
|
14045
14205
|
(_b3 = this._caddyChild.stdout) == null ? void 0 : _b3.on("data", (_data) => {
|
|
14046
14206
|
consola.info(_data.toString());
|
|
14047
|
-
|
|
14207
|
+
void resolveWhenReady();
|
|
14048
14208
|
});
|
|
14049
14209
|
setupCleanup();
|
|
14050
14210
|
} else {
|
|
14051
14211
|
consola.info("Caddy is running in another process.");
|
|
14052
|
-
|
|
14053
|
-
|
|
14212
|
+
void (async () => {
|
|
14213
|
+
try {
|
|
14214
|
+
if (https)
|
|
14215
|
+
await this.ensureTlsReady(targetHost);
|
|
14216
|
+
setupCleanup();
|
|
14217
|
+
resolve2();
|
|
14218
|
+
} catch (error) {
|
|
14219
|
+
reject2(error);
|
|
14220
|
+
}
|
|
14221
|
+
})();
|
|
14054
14222
|
}
|
|
14055
14223
|
});
|
|
14056
14224
|
}
|
|
14057
14225
|
async baseCleanup(restore = true) {
|
|
14058
|
-
var _a4;
|
|
14059
14226
|
this._stopEffects.forEach((fn) => fn());
|
|
14060
14227
|
try {
|
|
14061
14228
|
if (restore && this._source && this._target) {
|
|
14062
|
-
if (await removeHost(this._source.
|
|
14229
|
+
if (await removeHost(splitHostPort(this._source).host, splitHostPort(this._target).host))
|
|
14063
14230
|
consola.success("Restore host success.\n");
|
|
14064
14231
|
else
|
|
14065
14232
|
consola.fail("Restore host failed.\n");
|
|
@@ -14069,7 +14236,7 @@ ${line}
|
|
|
14069
14236
|
consola.fail("Restore host failed.\n");
|
|
14070
14237
|
}
|
|
14071
14238
|
if (!this.locked && !this.stoped) {
|
|
14072
|
-
|
|
14239
|
+
await this.stopCaddy();
|
|
14073
14240
|
try {
|
|
14074
14241
|
await lockfile.unlock(caddyLockFilePath).catch(() => {
|
|
14075
14242
|
});
|
package/dist/index.js
CHANGED
package/dist/nuxt.cjs
CHANGED
|
@@ -13456,7 +13456,7 @@ function validateTemplateContext(ctx) {
|
|
|
13456
13456
|
}
|
|
13457
13457
|
var caddyTemplate = `{
|
|
13458
13458
|
debug
|
|
13459
|
-
auto_https disable_redirects
|
|
13459
|
+
auto_https disable_redirects ignore_loaded_certs
|
|
13460
13460
|
}
|
|
13461
13461
|
|
|
13462
13462
|
:7601 {
|
|
@@ -13723,6 +13723,97 @@ function useCaddyConfig() {
|
|
|
13723
13723
|
};
|
|
13724
13724
|
}
|
|
13725
13725
|
|
|
13726
|
+
// src/caddy/log.ts
|
|
13727
|
+
function isCaddyReloadCancellation(line) {
|
|
13728
|
+
try {
|
|
13729
|
+
const entry = JSON.parse(line);
|
|
13730
|
+
return entry.logger === "tls" && typeof entry.error === "string" && entry.error.endsWith("context canceled");
|
|
13731
|
+
} catch {
|
|
13732
|
+
return false;
|
|
13733
|
+
}
|
|
13734
|
+
}
|
|
13735
|
+
|
|
13736
|
+
// src/caddy/tls-health.ts
|
|
13737
|
+
var import_node_tls = require("tls");
|
|
13738
|
+
function assessTlsCertificate(certificate, hostname, now = Date.now(), verifyHostname = import_node_tls.checkServerIdentity) {
|
|
13739
|
+
if (!certificate.valid_to)
|
|
13740
|
+
return { healthy: false, reason: "certificate_missing" };
|
|
13741
|
+
const expiresAt = new Date(certificate.valid_to);
|
|
13742
|
+
if (Number.isNaN(expiresAt.getTime()))
|
|
13743
|
+
return { healthy: false, reason: "certificate_invalid" };
|
|
13744
|
+
if (expiresAt.getTime() <= now)
|
|
13745
|
+
return { healthy: false, reason: "certificate_expired", expiresAt };
|
|
13746
|
+
try {
|
|
13747
|
+
if (verifyHostname(hostname, certificate))
|
|
13748
|
+
return { healthy: false, reason: "hostname_mismatch" };
|
|
13749
|
+
} catch {
|
|
13750
|
+
return { healthy: false, reason: "certificate_invalid" };
|
|
13751
|
+
}
|
|
13752
|
+
return { healthy: true, expiresAt };
|
|
13753
|
+
}
|
|
13754
|
+
function probeLocalTls(hostname, options = {}) {
|
|
13755
|
+
const {
|
|
13756
|
+
connect: openTlsConnection = import_node_tls.connect,
|
|
13757
|
+
port = 443,
|
|
13758
|
+
timeoutMs = 1e3
|
|
13759
|
+
} = options;
|
|
13760
|
+
return new Promise((resolve2) => {
|
|
13761
|
+
let settled = false;
|
|
13762
|
+
let timeout;
|
|
13763
|
+
const socket = openTlsConnection({
|
|
13764
|
+
host: "127.0.0.1",
|
|
13765
|
+
port,
|
|
13766
|
+
servername: hostname,
|
|
13767
|
+
rejectUnauthorized: false
|
|
13768
|
+
});
|
|
13769
|
+
const finish = (result) => {
|
|
13770
|
+
if (settled)
|
|
13771
|
+
return;
|
|
13772
|
+
settled = true;
|
|
13773
|
+
if (timeout)
|
|
13774
|
+
clearTimeout(timeout);
|
|
13775
|
+
socket.destroy();
|
|
13776
|
+
resolve2(result);
|
|
13777
|
+
};
|
|
13778
|
+
timeout = setTimeout(() => {
|
|
13779
|
+
finish({ healthy: false, reason: "connection_failed" });
|
|
13780
|
+
}, timeoutMs);
|
|
13781
|
+
socket.once("secureConnect", () => {
|
|
13782
|
+
finish(assessTlsCertificate(socket.getPeerCertificate(), hostname));
|
|
13783
|
+
});
|
|
13784
|
+
socket.once("error", () => {
|
|
13785
|
+
finish({ healthy: false, reason: "connection_failed" });
|
|
13786
|
+
});
|
|
13787
|
+
});
|
|
13788
|
+
}
|
|
13789
|
+
function sleep(ms) {
|
|
13790
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
13791
|
+
}
|
|
13792
|
+
async function waitForLocalTls(hostname, options = {}) {
|
|
13793
|
+
const {
|
|
13794
|
+
probe: checkTls = probeLocalTls,
|
|
13795
|
+
retryIntervalMs = 250,
|
|
13796
|
+
retryWindowMs = 3e4,
|
|
13797
|
+
sleep: wait = sleep,
|
|
13798
|
+
...probeOptions
|
|
13799
|
+
} = options;
|
|
13800
|
+
const deadline = Date.now() + retryWindowMs;
|
|
13801
|
+
let result = { healthy: false, reason: "connection_failed" };
|
|
13802
|
+
do {
|
|
13803
|
+
result = await checkTls(hostname, probeOptions);
|
|
13804
|
+
if (result.healthy)
|
|
13805
|
+
return result;
|
|
13806
|
+
const remaining = deadline - Date.now();
|
|
13807
|
+
if (remaining > 0)
|
|
13808
|
+
await wait(Math.min(retryIntervalMs, remaining));
|
|
13809
|
+
} while (Date.now() < deadline);
|
|
13810
|
+
return result;
|
|
13811
|
+
}
|
|
13812
|
+
function formatTlsHealthFailure(hostname, result) {
|
|
13813
|
+
const reason = result.reason === "certificate_expired" && result.expiresAt ? `the certificate expired at ${result.expiresAt.toISOString()}` : result.reason.replaceAll("_", " ");
|
|
13814
|
+
return `[unplugin-https-reverse-proxy] Caddy cannot serve valid HTTPS for ${hostname}: ${reason}. Restart Caddy to retry its automatic certificate renewal. Do not remove Caddy PKI data automatically because that replaces the trusted local root certificate.`;
|
|
13815
|
+
}
|
|
13816
|
+
|
|
13726
13817
|
// src/caddy/utils.ts
|
|
13727
13818
|
var import_node_child_process3 = require("child_process");
|
|
13728
13819
|
var import_node_net = require("net");
|
|
@@ -13860,6 +13951,17 @@ function getCaddyConfig() {
|
|
|
13860
13951
|
}
|
|
13861
13952
|
return caddyConfig;
|
|
13862
13953
|
}
|
|
13954
|
+
function splitHostPort(addr) {
|
|
13955
|
+
const lastColon = addr.lastIndexOf(":");
|
|
13956
|
+
if (lastColon === -1)
|
|
13957
|
+
return { host: addr, port: "" };
|
|
13958
|
+
if (addr.startsWith("[")) {
|
|
13959
|
+
const end = addr.indexOf("]");
|
|
13960
|
+
if (end !== -1 && addr[end + 1] === ":")
|
|
13961
|
+
return { host: addr.slice(1, end), port: addr.slice(end + 2) };
|
|
13962
|
+
}
|
|
13963
|
+
return { host: addr.slice(0, lastColon), port: addr.slice(lastColon + 1) };
|
|
13964
|
+
}
|
|
13863
13965
|
var CaddyInstant = class {
|
|
13864
13966
|
constructor() {
|
|
13865
13967
|
this.inited = false;
|
|
@@ -13901,12 +14003,46 @@ var CaddyInstant = class {
|
|
|
13901
14003
|
await download();
|
|
13902
14004
|
this.inited = true;
|
|
13903
14005
|
}
|
|
14006
|
+
async ensureTlsReady(targetHost) {
|
|
14007
|
+
const health = await waitForLocalTls(targetHost);
|
|
14008
|
+
if (!health.healthy)
|
|
14009
|
+
throw new Error(formatTlsHealthFailure(targetHost, health));
|
|
14010
|
+
}
|
|
14011
|
+
async updateCaddyfile() {
|
|
14012
|
+
const { configJsonRef } = getCaddyConfig();
|
|
14013
|
+
const proxies = Object.values(configJsonRef() || {});
|
|
14014
|
+
const ctx = validateTemplateContext({
|
|
14015
|
+
caddy_root: this.caddyRoot,
|
|
14016
|
+
proxies
|
|
14017
|
+
});
|
|
14018
|
+
this.caddyfile = await genCaddyfile(ctx);
|
|
14019
|
+
await this.writeCaddyfile();
|
|
14020
|
+
}
|
|
14021
|
+
async stopCaddy() {
|
|
14022
|
+
var _a4;
|
|
14023
|
+
try {
|
|
14024
|
+
await import_got_cjs.got.post("http://127.0.0.1:2019/stop", {
|
|
14025
|
+
headers: {
|
|
14026
|
+
Origin: "http://localhost:2019"
|
|
14027
|
+
},
|
|
14028
|
+
retry: {
|
|
14029
|
+
limit: 0
|
|
14030
|
+
},
|
|
14031
|
+
timeout: {
|
|
14032
|
+
request: 2e3
|
|
14033
|
+
}
|
|
14034
|
+
});
|
|
14035
|
+
} catch {
|
|
14036
|
+
}
|
|
14037
|
+
(_a4 = this._caddyChild) == null ? void 0 : _a4.kill();
|
|
14038
|
+
}
|
|
13904
14039
|
/**
|
|
13905
14040
|
* @param source like `127.0.0.1:8080`
|
|
13906
14041
|
* @param target like `test.abc.com`. And if you provide a port ,it will be ignore.
|
|
13907
14042
|
*/
|
|
13908
14043
|
async run(source, target, options) {
|
|
13909
14044
|
source = source.replace("0.0.0.0", "127.0.0.1");
|
|
14045
|
+
source = source.replace(/^localhost(?=:)/i, "127.0.0.1");
|
|
13910
14046
|
const {
|
|
13911
14047
|
restore = true,
|
|
13912
14048
|
base = "/",
|
|
@@ -13918,10 +14054,11 @@ var CaddyInstant = class {
|
|
|
13918
14054
|
this._target = target;
|
|
13919
14055
|
if (!this.inited)
|
|
13920
14056
|
await this.init();
|
|
13921
|
-
|
|
14057
|
+
const sourceHost = splitHostPort(source).host;
|
|
14058
|
+
const targetHost = splitHostPort(target).host;
|
|
14059
|
+
if (!await addHost(sourceHost, targetHost))
|
|
13922
14060
|
throw new Error("update host failed");
|
|
13923
14061
|
consola.success("update host success\n");
|
|
13924
|
-
const targetHost = target.split(":")[0];
|
|
13925
14062
|
const normalizeBase = (b) => {
|
|
13926
14063
|
let out = b || "/";
|
|
13927
14064
|
if (!out.startsWith("/"))
|
|
@@ -13943,16 +14080,16 @@ var CaddyInstant = class {
|
|
|
13943
14080
|
];
|
|
13944
14081
|
const { writeCaddyConfig } = getCaddyConfig();
|
|
13945
14082
|
writeCaddyConfig(proxies);
|
|
14083
|
+
await this.updateCaddyfile();
|
|
14084
|
+
let skipInitialCaddyfileEffect = true;
|
|
13946
14085
|
this._stopEffects.push(
|
|
13947
|
-
effect(
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
this.caddyfile = await genCaddyfile(ctx);
|
|
13955
|
-
await this.writeCaddyfile();
|
|
14086
|
+
effect(() => {
|
|
14087
|
+
getCaddyConfig().configJsonRef();
|
|
14088
|
+
if (skipInitialCaddyfileEffect) {
|
|
14089
|
+
skipInitialCaddyfileEffect = false;
|
|
14090
|
+
return;
|
|
14091
|
+
}
|
|
14092
|
+
void this.updateCaddyfile();
|
|
13956
14093
|
})
|
|
13957
14094
|
);
|
|
13958
14095
|
if (!(0, import_node_fs3.existsSync)(caddyLockFilePath))
|
|
@@ -13965,6 +14102,21 @@ var CaddyInstant = class {
|
|
|
13965
14102
|
}
|
|
13966
14103
|
return new Promise((resolve2, reject2) => {
|
|
13967
14104
|
var _a4, _b3;
|
|
14105
|
+
let startupCheckStarted = false;
|
|
14106
|
+
const resolveWhenReady = async () => {
|
|
14107
|
+
if (startupCheckStarted)
|
|
14108
|
+
return;
|
|
14109
|
+
startupCheckStarted = true;
|
|
14110
|
+
try {
|
|
14111
|
+
if (https)
|
|
14112
|
+
await this.ensureTlsReady(targetHost);
|
|
14113
|
+
resolve2();
|
|
14114
|
+
} catch (error) {
|
|
14115
|
+
if (!this.locked)
|
|
14116
|
+
await this.baseCleanup(restore);
|
|
14117
|
+
reject2(error);
|
|
14118
|
+
}
|
|
14119
|
+
};
|
|
13968
14120
|
const setupCleanup = () => {
|
|
13969
14121
|
import_node_process4.default.on("SIGINT", async () => {
|
|
13970
14122
|
if (this.stoped)
|
|
@@ -13981,7 +14133,7 @@ var CaddyInstant = class {
|
|
|
13981
14133
|
});
|
|
13982
14134
|
const originalExit = import_node_process4.default.exit.bind(import_node_process4.default);
|
|
13983
14135
|
import_node_process4.default.exit = async (code) => {
|
|
13984
|
-
const port = Number(source.
|
|
14136
|
+
const port = Number(splitHostPort(source).port);
|
|
13985
14137
|
if (!Number.isNaN(port) && await tryPort(port))
|
|
13986
14138
|
await kill(port);
|
|
13987
14139
|
const pwd = import_node_process4.default.cwd();
|
|
@@ -13989,6 +14141,10 @@ var CaddyInstant = class {
|
|
|
13989
14141
|
if ((0, import_node_fs3.existsSync)(viteCacheDir))
|
|
13990
14142
|
await chmodRecursive(viteCacheDir, 511).catch(() => {
|
|
13991
14143
|
});
|
|
14144
|
+
const viteTempCacheDir = `${pwd}/node_modules/.vite-temp`;
|
|
14145
|
+
if ((0, import_node_fs3.existsSync)(viteTempCacheDir))
|
|
14146
|
+
await chmodRecursive(viteTempCacheDir, 511).catch(() => {
|
|
14147
|
+
});
|
|
13992
14148
|
const nuxtCacheDir = `${pwd}/.nuxt`;
|
|
13993
14149
|
if ((0, import_node_fs3.existsSync)(nuxtCacheDir))
|
|
13994
14150
|
await chmodRecursive(nuxtCacheDir, 511).catch(() => {
|
|
@@ -14020,6 +14176,10 @@ var CaddyInstant = class {
|
|
|
14020
14176
|
const lines = data.toString().split("\n").map((line) => line.trim());
|
|
14021
14177
|
for (const line of lines) {
|
|
14022
14178
|
showCaddyLog && line && console.info(line);
|
|
14179
|
+
if (isCaddyReloadCancellation(line)) {
|
|
14180
|
+
consola.info("Caddy restarted before TLS issuance completed; retrying.\n");
|
|
14181
|
+
continue;
|
|
14182
|
+
}
|
|
14023
14183
|
try {
|
|
14024
14184
|
if (line.includes("Error:") || line && JSON.parse(line).level === "error") {
|
|
14025
14185
|
if (line.includes("parsing caddyfile tokens")) {
|
|
@@ -14040,27 +14200,34 @@ ${line}
|
|
|
14040
14200
|
if (line.includes("config file changed"))
|
|
14041
14201
|
consola.success("Detect added a new reverse proxy config, restarted.\n");
|
|
14042
14202
|
if (line.includes("caddy proxying") || line.includes("serving initial"))
|
|
14043
|
-
|
|
14203
|
+
void resolveWhenReady();
|
|
14044
14204
|
}
|
|
14045
14205
|
});
|
|
14046
14206
|
(_b3 = this._caddyChild.stdout) == null ? void 0 : _b3.on("data", (_data) => {
|
|
14047
14207
|
consola.info(_data.toString());
|
|
14048
|
-
|
|
14208
|
+
void resolveWhenReady();
|
|
14049
14209
|
});
|
|
14050
14210
|
setupCleanup();
|
|
14051
14211
|
} else {
|
|
14052
14212
|
consola.info("Caddy is running in another process.");
|
|
14053
|
-
|
|
14054
|
-
|
|
14213
|
+
void (async () => {
|
|
14214
|
+
try {
|
|
14215
|
+
if (https)
|
|
14216
|
+
await this.ensureTlsReady(targetHost);
|
|
14217
|
+
setupCleanup();
|
|
14218
|
+
resolve2();
|
|
14219
|
+
} catch (error) {
|
|
14220
|
+
reject2(error);
|
|
14221
|
+
}
|
|
14222
|
+
})();
|
|
14055
14223
|
}
|
|
14056
14224
|
});
|
|
14057
14225
|
}
|
|
14058
14226
|
async baseCleanup(restore = true) {
|
|
14059
|
-
var _a4;
|
|
14060
14227
|
this._stopEffects.forEach((fn) => fn());
|
|
14061
14228
|
try {
|
|
14062
14229
|
if (restore && this._source && this._target) {
|
|
14063
|
-
if (await removeHost(this._source.
|
|
14230
|
+
if (await removeHost(splitHostPort(this._source).host, splitHostPort(this._target).host))
|
|
14064
14231
|
consola.success("Restore host success.\n");
|
|
14065
14232
|
else
|
|
14066
14233
|
consola.fail("Restore host failed.\n");
|
|
@@ -14070,7 +14237,7 @@ ${line}
|
|
|
14070
14237
|
consola.fail("Restore host failed.\n");
|
|
14071
14238
|
}
|
|
14072
14239
|
if (!this.locked && !this.stoped) {
|
|
14073
|
-
|
|
14240
|
+
await this.stopCaddy();
|
|
14074
14241
|
try {
|
|
14075
14242
|
await lockfile.unlock(caddyLockFilePath).catch(() => {
|
|
14076
14243
|
});
|