mirror of
https://github.com/lush2020/edgetunnel.git
synced 2026-03-21 17:12:33 +08:00
fix: 优化ECH链接生成逻辑,确保正确处理ECH配置并简化域名替换功能
This commit is contained in:
48
_worker.js
48
_worker.js
@@ -279,7 +279,7 @@ export default {
|
||||
return new Response('优选订阅生成器异常:' + error.message, { status: 403 });
|
||||
}
|
||||
}
|
||||
const ECHLINK参数 = config_JSON.ECH ? '&ech=ECHConfigList+cloudflare-ech.com' : '';
|
||||
const ECHLINK参数 = config_JSON.ECH ? '&ech=' + encodeURIComponent(await getECH(config_JSON.HOST)) : '';
|
||||
订阅内容 = 其他节点LINK + 完整优选IP.map(原始地址 => {
|
||||
// 统一正则: 匹配 域名/IPv4/IPv6地址 + 可选端口 + 可选备注
|
||||
// 示例:
|
||||
@@ -301,7 +301,7 @@ export default {
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${协议类型}://00000000-0000-4000-8000-000000000000@${节点地址}:${节点端口}?security=tls${ECHLINK参数}&type=${config_JSON.传输协议}&host=example.com&sni=example.com&path=${encodeURIComponent(config_JSON.随机路径 ? 随机路径() + 节点路径 : 节点路径) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(节点备注)}`;
|
||||
return `${协议类型}://00000000-0000-4000-8000-000000000000@${节点地址}:${节点端口}?security=tls&type=${config_JSON.传输协议 + ECHLINK参数}&host=example.com&sni=example.com&path=${encodeURIComponent(config_JSON.随机路径 ? 随机路径() + 节点路径 : 节点路径) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(节点备注)}`;
|
||||
}).filter(item => item !== null).join('\n');
|
||||
} else { // 订阅转换
|
||||
const 订阅转换URL = `${config_JSON.订阅转换配置.SUBAPI}/sub?target=${订阅类型}&url=${encodeURIComponent(url.protocol + '//' + url.host + '/sub?target=mixed&token=' + 订阅TOKEN + (url.searchParams.has('sub') && url.searchParams.get('sub') != '' ? `&sub=${url.searchParams.get('sub')}` : ''))}&config=${encodeURIComponent(config_JSON.订阅转换配置.SUBCONFIG)}&emoji=${config_JSON.订阅转换配置.SUBEMOJI}&scv=${config_JSON.跳过证书验证}`;
|
||||
@@ -1061,48 +1061,14 @@ function 随机替换通配符(h) {
|
||||
});
|
||||
}
|
||||
|
||||
// ECHConfigList缓存,用于存储host对应的ECH配置
|
||||
const ECHConfigCache = new Map();
|
||||
async function 批量替换域名(内容, hosts, 每组数量 = 2) {
|
||||
function 批量替换域名(内容, hosts, 每组数量 = 2) {
|
||||
const 打乱后数组 = [...hosts].sort(() => Math.random() - 0.5);
|
||||
let count = 0, currentRandomHost = null;
|
||||
const hostGroups = []; // 记录每组对应的host
|
||||
|
||||
// 第一步:替换所有 example.com,并记录每组对应的 host
|
||||
let 替换后内容 = 内容.replace(/example\.com/g, () => {
|
||||
if (count % 每组数量 === 0) {
|
||||
currentRandomHost = 随机替换通配符(打乱后数组[Math.floor(count / 每组数量) % 打乱后数组.length]);
|
||||
hostGroups.push(currentRandomHost);
|
||||
}
|
||||
return 内容.replace(/example\.com/g, () => {
|
||||
if (count % 每组数量 === 0) currentRandomHost = 随机替换通配符(打乱后数组[Math.floor(count / 每组数量) % 打乱后数组.length]);
|
||||
count++;
|
||||
return currentRandomHost;
|
||||
});
|
||||
|
||||
// 第二步:检查是否存在 ECHConfigList+cloudflare-ech.com 需要替换
|
||||
const echPattern = /ECHConfigList\+cloudflare-ech\.com/g;
|
||||
if (!echPattern.test(替换后内容)) {
|
||||
return 替换后内容;
|
||||
}
|
||||
|
||||
// 第三步:为每个 host 获取 ECH 配置(使用缓存避免重复请求)
|
||||
for (const host of hostGroups) {
|
||||
if (!ECHConfigCache.has(host)) {
|
||||
const ech = encodeURIComponent(await getECH(host));
|
||||
ECHConfigCache.set(host, ech || '');
|
||||
}
|
||||
}
|
||||
|
||||
// 第四步:按顺序替换 ECHConfigList+cloudflare-ech.com
|
||||
// 每组数量个 host 替换对应一个 ech 替换
|
||||
let echIndex = 0;
|
||||
替换后内容 = 替换后内容.replace(/ECHConfigList\+cloudflare-ech\.com/g, () => {
|
||||
const host = hostGroups[echIndex % hostGroups.length];
|
||||
const ech = ECHConfigCache.get(host) || '';
|
||||
echIndex++;
|
||||
return ech;
|
||||
});
|
||||
|
||||
return 替换后内容;
|
||||
}
|
||||
|
||||
async function getECH(host) {
|
||||
@@ -1220,8 +1186,8 @@ async function 读取config_JSON(env, hostname, userID, path, 重置配置 = fal
|
||||
config_JSON.PATH = path ? (path.startsWith('/') ? path : '/' + path) : (config_JSON.反代.SOCKS5.启用 ? ('/' + config_JSON.反代.SOCKS5.启用 + (config_JSON.反代.SOCKS5.全局 ? '://' : '=') + config_JSON.反代.SOCKS5.账号) : (config_JSON.反代.PROXYIP === 'auto' ? '/' : `/proxyip=${config_JSON.反代.PROXYIP}`));
|
||||
const TLS分片参数 = config_JSON.TLS分片 == 'Shadowrocket' ? `&fragment=${encodeURIComponent('1,40-60,30-50,tlshello')}` : config_JSON.TLS分片 == 'Happ' ? `&fragment=${encodeURIComponent('3,1,tlshello')}` : '';
|
||||
if (!config_JSON.ECH) config_JSON.ECH = false;
|
||||
const ECH参数 = config_JSON.ECH ? '&ech=' + encodeURIComponent(await getECH(host)) : '';
|
||||
config_JSON.LINK = `${config_JSON.协议类型}://${userID}@${host}:443?security=tls&type=${config_JSON.传输协议 + ECH参数}&host=${host}&sni=${host}&path=${encodeURIComponent(config_JSON.启用0RTT ? config_JSON.PATH + '?ed=2560' : config_JSON.PATH) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(config_JSON.优选订阅生成.SUBNAME)}`;
|
||||
const ECHLINK参数 = config_JSON.ECH ? '&ech=' + encodeURIComponent(await getECH(config_JSON.HOST)) : '';
|
||||
config_JSON.LINK = `${config_JSON.协议类型}://${userID}@${host}:443?security=tls&type=${config_JSON.传输协议 + ECHLINK参数}&host=${host}&sni=${host}&path=${encodeURIComponent(config_JSON.启用0RTT ? config_JSON.PATH + '?ed=2560' : config_JSON.PATH) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(config_JSON.优选订阅生成.SUBNAME)}`;
|
||||
config_JSON.优选订阅生成.TOKEN = await MD5MD5(hostname + userID);
|
||||
|
||||
const 初始化TG_JSON = { BotToken: null, ChatID: null };
|
||||
|
||||
Reference in New Issue
Block a user