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