Compare commits

..

6 Commits

10 changed files with 96 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.14.388",
"version": "2.14.394",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

View File

@@ -292,6 +292,7 @@ export const ProxyUtils = {
getISO,
MMDB,
Gist,
download,
};
function tryParse(parser, line) {

View File

@@ -50,10 +50,32 @@ function Clash() {
};
const parse = function (raw) {
// Clash YAML format
// 防止 VLESS节点 reality-opts 选项中的 short-id 被解析成 Infinity
// 匹配 short-id 冒号后面的值(包含空格和引号)
const afterReplace = raw.replace(
/short-id:([ ]*[^,\n}]*)/g,
(matched, value) => {
const afterTrim = value.trim();
// 为空
if (!afterTrim || afterTrim === '') {
return 'short-id: ""'
}
// 是否被引号包裹
if (/^(['"]).*\1$/.test(afterTrim)) {
return `short-id: ${afterTrim}`;
} else {
return `short-id: "${afterTrim}"`
}
}
);
const {
proxies,
'global-client-fingerprint': globalClientFingerprint,
} = safeLoad(raw);
} = safeLoad(afterReplace);
return proxies
.map((p) => {
// https://github.com/MetaCubeX/mihomo/blob/Alpha/docs/config.yaml#L73C1-L73C26

View File

@@ -69,6 +69,7 @@ async function downloadSubscription(req, res) {
produceType,
includeUnsupportedProxy,
resultFormat,
proxy,
} = req.query;
let $options = {};
if (req.query.$options) {
@@ -92,6 +93,10 @@ async function downloadSubscription(req, res) {
url = decodeURIComponent(url);
$.info(`指定远程订阅 URL: ${url}`);
}
if (proxy) {
proxy = decodeURIComponent(proxy);
$.info(`指定远程订阅使用代理/策略 proxy: ${proxy}`);
}
if (ua) {
ua = decodeURIComponent(ua);
$.info(`指定远程订阅 User-Agent: ${ua}`);
@@ -135,6 +140,7 @@ async function downloadSubscription(req, res) {
'include-unsupported-proxy': includeUnsupportedProxy,
},
$options,
proxy,
});
if (
@@ -175,7 +181,7 @@ async function downloadSubscription(req, res) {
url,
$arguments.flowUserAgent,
undefined,
sub.proxy,
proxy || sub.proxy,
$arguments.flowUrl,
);
if (flowInfo) {
@@ -264,6 +270,7 @@ async function downloadCollection(req, res) {
produceType,
includeUnsupportedProxy,
resultFormat,
proxy,
} = req.query;
let $options = {};
@@ -285,6 +292,11 @@ async function downloadCollection(req, res) {
$.info(`传入 $options: ${JSON.stringify($options)}`);
}
if (proxy) {
proxy = decodeURIComponent(proxy);
$.info(`指定远程订阅使用代理/策略 proxy: ${proxy}`);
}
if (ignoreFailedRemoteSub != null && ignoreFailedRemoteSub !== '') {
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
@@ -311,6 +323,7 @@ async function downloadCollection(req, res) {
'include-unsupported-proxy': includeUnsupportedProxy,
},
$options,
proxy,
});
// forward flow header from the first subscription in this collection
@@ -355,7 +368,7 @@ async function downloadCollection(req, res) {
url,
$arguments.flowUserAgent,
undefined,
sub.proxy,
proxy || sub.proxy || collection.proxy,
$arguments.flowUrl,
);
if (flowInfo) {

View File

@@ -59,6 +59,7 @@ async function getFile(req, res) {
content,
mergeSources,
ignoreFailedRemoteFile,
proxy,
} = req.query;
let $options = {};
if (req.query.$options) {
@@ -82,6 +83,10 @@ async function getFile(req, res) {
url = decodeURIComponent(url);
$.info(`指定远程文件 URL: ${url}`);
}
if (proxy) {
proxy = decodeURIComponent(proxy);
$.info(`指定远程订阅使用代理/策略 proxy: ${proxy}`);
}
if (ua) {
ua = decodeURIComponent(ua);
$.info(`指定远程文件 User-Agent: ${ua}`);
@@ -120,6 +125,7 @@ async function getFile(req, res) {
mergeSources,
ignoreFailedRemoteFile,
$options,
proxy,
});
try {
@@ -129,6 +135,8 @@ async function getFile(req, res) {
const flowInfo = await getFlowHeaders(
subInfoUrl,
subInfoUserAgent || file.subInfoUserAgent,
undefined,
proxy || file.proxy,
);
if (flowInfo) {
res.set('subscription-userinfo', flowInfo);

View File

@@ -38,6 +38,7 @@ async function produceArtifact({
subscription,
awaitCustomCache,
$options,
proxy,
}) {
platform = platform || 'JSON';
@@ -68,7 +69,7 @@ async function produceArtifact({
url,
ua || sub.ua,
undefined,
sub.proxy,
proxy || sub.proxy,
undefined,
awaitCustomCache,
);
@@ -115,7 +116,7 @@ async function produceArtifact({
url,
ua || sub.ua,
undefined,
sub.proxy,
proxy || sub.proxy,
undefined,
awaitCustomCache,
);
@@ -189,7 +190,20 @@ async function produceArtifact({
const allCols = $.read(COLLECTIONS_KEY);
const collection = findByName(allCols, name);
if (!collection) throw new Error(`找不到组合订阅 ${name}`);
const subnames = collection.subscriptions;
const subnames = [...collection.subscriptions];
let subscriptionTags = collection.subscriptionTags;
if (Array.isArray(subscriptionTags) && subscriptionTags.length > 0) {
allSubs.forEach((sub) => {
if (
Array.isArray(sub.tag) &&
sub.tag.length > 0 &&
!subnames.includes(sub.name) &&
sub.tag.some((tag) => subscriptionTags.includes(tag))
) {
subnames.push(sub.name);
}
});
}
const results = {};
const errors = {};
let processed = 0;
@@ -220,7 +234,9 @@ async function produceArtifact({
url,
sub.ua,
undefined,
sub.proxy,
proxy ||
sub.proxy ||
collection.proxy,
);
} catch (err) {
errors[url] = err;
@@ -344,7 +360,6 @@ async function produceArtifact({
}
exist[proxy.name] = true;
}
console.log(proxies);
return ProxyUtils.produce(proxies, platform, produceType, produceOpts);
} else if (type === 'rule') {
const allRules = $.read(RULES_KEY);
@@ -390,7 +405,12 @@ async function produceArtifact({
.filter((i) => i.length)
.map(async (url) => {
try {
return await download(url, ua || file.ua);
return await download(
url,
ua || file.ua,
undefined,
file.proxy || proxy,
);
} catch (err) {
errors[url] = err;
$.error(
@@ -433,7 +453,12 @@ async function produceArtifact({
.filter((i) => i.length)
.map(async (url) => {
try {
return await download(url, ua || file.ua);
return await download(
url,
ua || file.ua,
undefined,
file.proxy || proxy,
);
} catch (err) {
errors[url] = err;
$.error(

View File

@@ -45,7 +45,10 @@ export default async function download(
const { isNode, isStash, isLoon, isShadowRocket, isQX } = ENV();
const { defaultProxy, defaultUserAgent, defaultTimeout, cacheThreshold } =
$.read(SETTINGS_KEY);
const proxy = customProxy || defaultProxy;
let proxy = customProxy || defaultProxy;
if ($.env.isNode) {
proxy = proxy || eval('process.env.SUB_STORE_BACKEND_DEFAULT_PROXY');
}
const userAgent = ua || defaultUserAgent || 'clash.meta';
const requestTimeout = timeout || defaultTimeout;
const id = hex_md5(userAgent + url);

View File

@@ -49,7 +49,11 @@ export async function getFlowHeaders(
} else {
const { defaultProxy, defaultFlowUserAgent, defaultTimeout } =
$.read(SETTINGS_KEY);
const proxy = customProxy || defaultProxy;
let proxy = customProxy || defaultProxy;
if ($.env.isNode) {
proxy =
proxy || eval('process.env.SUB_STORE_BACKEND_DEFAULT_PROXY');
}
const userAgent =
ua ||
defaultFlowUserAgent ||

View File

@@ -9,8 +9,12 @@ import { SETTINGS_KEY } from '@/constants';
export default class Gist {
constructor({ token, key, syncPlatform }) {
const { isStash, isLoon, isShadowRocket, isQX } = ENV();
const { defaultProxy: proxy, defaultTimeout: timeout } =
$.read(SETTINGS_KEY);
const { defaultProxy, defaultTimeout: timeout } = $.read(SETTINGS_KEY);
let proxy = defaultProxy;
if ($.env.isNode) {
proxy =
proxy || eval('process.env.SUB_STORE_BACKEND_DEFAULT_PROXY');
}
if (syncPlatform === 'gitlab') {
this.headers = {

View File

@@ -66,6 +66,7 @@ function operator(proxies = [], targetPlatform, context) {
// removeFlag, // 移除 emoji 旗帜
// getISO, // 获取 ISO 3166-1 alpha-2 代码
// Gist, // Gist 类
// download, // 内部的下载方法, 见 backend/src/utils/download.js
// }
// 如果只是为了快速修改或者筛选 可以参考 脚本操作支持节点快捷脚本 https://t.me/zhetengsha/970 和 脚本筛选支持节点快捷脚本 https://t.me/zhetengsha/1009