diff --git a/package.json b/package.json index ab45faf..3bb628f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "unplugin-https-reverse-proxy", "type": "module", - "version": "4.0.1", + "version": "4.0.2", "description": "", "license": "MIT", "homepage": "https://github.com/zcf0508/unplugin-https-reverse-proxy#readme", diff --git a/src/caddy/index.ts b/src/caddy/index.ts index ba4280c..86b343c 100644 --- a/src/caddy/index.ts +++ b/src/caddy/index.ts @@ -114,6 +114,19 @@ function getCaddyConfig(): ReturnType { return caddyConfig } +/** Split `host:port` (IPv4 or hostname); supports `[::1]:port`. */ +function splitHostPort(addr: string): { host: string, port: string } { + const lastColon = addr.lastIndexOf(':') + if (lastColon === -1) + return { host: addr, port: '' } + if (addr.startsWith('[')) { + const end = addr.indexOf(']') + if (end !== -1 && addr[end + 1] === ':') + return { host: addr.slice(1, end), port: addr.slice(end + 2) } + } + return { host: addr.slice(0, lastColon), port: addr.slice(lastColon + 1) } +} + export class CaddyInstant { private inited = false private stoped = false @@ -180,6 +193,9 @@ export class CaddyInstant { */ async run(source: string, target: string, options?: Partial): Promise { source = source.replace('0.0.0.0', '127.0.0.1') + // Caddy dials the upstream host via DNS; `localhost` can hit lookup timeouts (VPN/DNS). + // Use loopback IP so the proxy never depends on resolving "localhost". + source = source.replace(/^localhost(?=:)/i, '127.0.0.1') const { restore = true, base = '/', @@ -194,11 +210,11 @@ export class CaddyInstant { if (!this.inited) await this.init() - if (!await addHost(source.split(':')[0], target.split(':')[0])) + const sourceHost = splitHostPort(source).host + const targetHost = splitHostPort(target).host + if (!await addHost(sourceHost, targetHost)) throw new Error('update host failed') consola.success('update host success\n') - - const targetHost = target.split(':')[0] const normalizeBase = (b: string): string => { let out = b || '/' if (!out.startsWith('/')) @@ -270,7 +286,7 @@ export class CaddyInstant { // @ts-expect-error override process.exit = async (code?: number) => { - const port = Number(source.split(':')[1]) + const port = Number(splitHostPort(source).port) if (!Number.isNaN(port) && await tryPort(port)) await kill(port) @@ -279,6 +295,9 @@ export class CaddyInstant { const viteCacheDir = `${pwd}/node_modules/.vite` if (existsSync(viteCacheDir)) await chmodRecursive(viteCacheDir, 0o777).catch(() => { }) + const viteTempCacheDir = `${pwd}/node_modules/.vite-temp` + if (existsSync(viteTempCacheDir)) + await chmodRecursive(viteTempCacheDir, 0o777).catch(() => { }) const nuxtCacheDir = `${pwd}/.nuxt` if (existsSync(nuxtCacheDir)) await chmodRecursive(nuxtCacheDir, 0o777).catch(() => { }) @@ -367,7 +386,7 @@ export class CaddyInstant { try { if (restore && this._source && this._target) { - if (await removeHost(this._source.split(':')[0], this._target.split(':')[0])) + if (await removeHost(splitHostPort(this._source).host, splitHostPort(this._target).host)) consola.success('Restore host success.\n') else