Compare commits

..

1 Commits

Author SHA1 Message Date
xream
cd352cd574 feat: 支持使用代理/节点获取订阅 2024-03-13 01:55:16 +08:00
10 changed files with 20 additions and 78 deletions

View File

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

View File

@@ -231,10 +231,6 @@ const sshParser = (proxy = {}) => {
// https://wiki.metacubex.one/config/proxies/ssh
// https://sing-box.sagernet.org/zh/configuration/outbound/ssh
if (proxy['privateKey']) parsedProxy.private_key_path = proxy['privateKey'];
if (proxy['private-key'])
parsedProxy.private_key_path = proxy['private-key'];
if (proxy['private-key-passphrase'])
parsedProxy.private_key_passphrase = proxy['private-key-passphrase'];
if (proxy['server-fingerprint']) {
parsedProxy.host_key = [proxy['server-fingerprint']];
// https://manual.nssurge.com/policy/ssh.html
@@ -244,9 +240,6 @@ const sshParser = (proxy = {}) => {
proxy['server-fingerprint'].split(' ')[0],
];
}
if (proxy['host-key']) parsedProxy.host_key = proxy['host-key'];
if (proxy['host-key-algorithms'])
parsedProxy.host_key_algorithms = proxy['host-key-algorithms'];
if (proxy['fast-open']) parsedProxy.udp_fragment = true;
tfoParser(proxy, parsedProxy);
return parsedProxy;

View File

@@ -10,8 +10,6 @@ const RULE_TYPES_MAPPING = [
[/^PROTOCOL$/, 'PROTOCOL'],
[/^IP-CIDR$/i, 'IP-CIDR'],
[/^(IP-CIDR6|ip6-cidr|IP6-CIDR)$/, 'IP-CIDR6'],
[/^GEOIP$/i, 'GEOIP'],
[/^GEOSITE$/i, 'GEOSITE'],
];
function AllRuleParser() {
@@ -39,7 +37,8 @@ function AllRuleParser() {
content: params[1],
};
if (
['IP-CIDR', 'IP-CIDR6', 'GEOIP'].includes(rule.type)
rule.type === 'IP-CIDR' ||
rule.type === 'IP-CIDR6'
) {
rule.options = params.slice(2);
}

View File

@@ -10,8 +10,6 @@ function QXFilter() {
'SRC-IP',
'IN-PORT',
'PROTOCOL',
'GEOSITE',
'GEOIP',
];
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
@@ -31,8 +29,6 @@ function QXFilter() {
function SurgeRuleSet() {
const type = 'SINGLE';
const func = (rule) => {
const UNSUPPORTED = ['GEOSITE', 'GEOIP'];
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
let output = `${rule.type},${rule.content}`;
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type)) {
output +=
@@ -47,7 +43,7 @@ function LoonRules() {
const type = 'SINGLE';
const func = (rule) => {
// skip unsupported rules
const UNSUPPORTED = ['SRC-IP', 'GEOSITE', 'GEOIP'];
const UNSUPPORTED = ['DEST-PORT', 'SRC-IP', 'IN-PORT', 'PROTOCOL'];
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type) && rule.options) {
// Loon only supports the no-resolve option
@@ -73,7 +69,7 @@ function ClashRuleProvider() {
let output = `${TRANSFORM[rule.type] || rule.type},${
rule.content
}`;
if (['IP-CIDR', 'IP-CIDR6', 'GEOIP'].includes(rule.type)) {
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type)) {
if (rule.options) {
// Clash only supports the no-resolve option
rule.options = rule.options.filter((option) =>

View File

@@ -113,7 +113,7 @@ async function downloadSubscription(req, res) {
// forward flow headers
const flowInfo = await getFlowHeaders(
url,
$arguments.flowUserAgent,
undefined,
undefined,
sub.proxy,
);
@@ -250,7 +250,7 @@ async function downloadCollection(req, res) {
if (!$arguments.noFlow) {
const flowInfo = await getFlowHeaders(
url,
$arguments.flowUserAgent,
undefined,
undefined,
sub.proxy,
);

View File

@@ -115,7 +115,7 @@ async function getFlowInfo(req, res) {
} else {
const flowHeaders = await getFlowHeaders(
url,
$arguments.flowUserAgent,
undefined,
undefined,
sub.proxy,
);

View File

@@ -1,7 +1,6 @@
import { SETTINGS_KEY } from '@/constants';
import { HTTP, ENV } from '@/vendor/open-api';
import { hex_md5 } from '@/vendor/md5';
import { getPolicyDescriptor } from '@/utils';
import resourceCache from '@/utils/resource-cache';
import headersResourceCache from '@/utils/headers-resource-cache';
import {
@@ -53,7 +52,7 @@ export default async function download(rawUrl, ua, timeout, proxy) {
// return item.content;
// }
const { isNode, isStash, isLoon, isShadowRocket, isQX } = ENV();
const { isNode } = ENV();
const { defaultUserAgent, defaultTimeout, cacheThreshold } =
$.read(SETTINGS_KEY);
const userAgent = ua || defaultUserAgent || 'clash.meta';
@@ -66,10 +65,6 @@ export default async function download(rawUrl, ua, timeout, proxy) {
const http = HTTP({
headers: {
'User-Agent': userAgent,
...(isStash && proxy
? { 'X-Stash-Selected-Proxy': encodeURIComponent(proxy) }
: {}),
...(isShadowRocket && proxy ? { 'X-Surge-Policy': proxy } : {}),
},
timeout: requestTimeout,
});
@@ -88,10 +83,9 @@ export default async function download(rawUrl, ua, timeout, proxy) {
try {
const { body, headers } = await http.get({
url,
...(proxy ? { proxy } : {}),
...(isLoon && proxy ? { node: proxy } : {}),
...(isQX && proxy ? { opts: { policy: proxy } } : {}),
...(proxy ? getPolicyDescriptor(proxy) : {}),
proxy,
node: proxy,
'policy-descriptor': proxy,
});
if (headers) {
@@ -129,12 +123,7 @@ export default async function download(rawUrl, ua, timeout, proxy) {
if ($arguments?.validCheck) {
await validCheck(
parseFlowHeaders(
await getFlowHeaders(
url,
$arguments.flowUserAgent,
undefined,
proxy,
),
await getFlowHeaders(url, undefined, undefined, proxy),
),
);
}

View File

@@ -1,6 +1,5 @@
import { SETTINGS_KEY } from '@/constants';
import { HTTP, ENV } from '@/vendor/open-api';
import { getPolicyDescriptor } from '@/utils';
import { HTTP } from '@/vendor/open-api';
import $ from '@/core/app';
import headersResourceCache from '@/utils/headers-resource-cache';
@@ -34,7 +33,6 @@ export async function getFlowHeaders(rawUrl, ua, timeout, proxy) {
if ($arguments?.noFlow) {
return;
}
const { isStash, isLoon, isShadowRocket, isQX } = ENV();
const cached = headersResourceCache.get(url);
let flowInfo;
if (!$arguments?.noCache && cached) {
@@ -49,11 +47,7 @@ export async function getFlowHeaders(rawUrl, ua, timeout, proxy) {
const requestTimeout = timeout || defaultTimeout;
const http = HTTP();
try {
$.info(
`使用 HEAD 方法获取流量信息: ${url}, User-Agent: ${
userAgent || ''
}`,
);
// $.info(`使用 HEAD 方法获取流量信息: ${url}`);
const { headers } = await http.head({
url: url
.split(/[\r\n]+/)
@@ -61,36 +55,20 @@ export async function getFlowHeaders(rawUrl, ua, timeout, proxy) {
.filter((i) => i.length)[0],
headers: {
'User-Agent': userAgent,
...(isStash && proxy
? {
'X-Stash-Selected-Proxy':
encodeURIComponent(proxy),
}
: {}),
...(isShadowRocket && proxy
? { 'X-Surge-Policy': proxy }
: {}),
},
timeout: requestTimeout,
...(proxy ? { proxy } : {}),
...(isLoon && proxy ? { node: proxy } : {}),
...(isQX && proxy ? { opts: { policy: proxy } } : {}),
...(proxy ? getPolicyDescriptor(proxy) : {}),
proxy,
node: proxy,
'policy-descriptor': proxy,
});
flowInfo = getFlowField(headers);
} catch (e) {
$.error(
`使用 HEAD 方法获取流量信息失败: ${url}, User-Agent: ${
userAgent || ''
}: ${e.message ?? e}`,
`使用 HEAD 方法获取流量信息失败: ${url}: ${e.message ?? e}`,
);
}
if (!flowInfo) {
$.info(
`使用 GET 方法获取流量信息: ${url}, User-Agent: ${
userAgent || ''
}`,
);
$.info(`使用 GET 方法获取流量信息: ${url}`);
const { headers } = await http.get({
url: url
.split(/[\r\n]+/)

View File

@@ -35,17 +35,6 @@ function getIfPresent(obj, defaultValue) {
return isPresent(obj) ? obj : defaultValue;
}
function getPolicyDescriptor(str) {
if (!str) return {};
return /^.+?\s*?=\s*?.+?\s*?,.+?/.test(str)
? {
'policy-descriptor': str,
}
: {
policy: str,
};
}
const utf8ArrayToStr =
typeof TextDecoder !== 'undefined'
? (v) => new TextDecoder().decode(new Uint8Array(v))
@@ -102,5 +91,4 @@ export {
isPresent,
getIfPresent,
utf8ArrayToStr,
getPolicyDescriptor,
};

View File

@@ -316,7 +316,6 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
url: options.url,
headers: options.headers,
body: options.body,
opts: options.opts,
});
} else if (isLoon || isSurge || isNode) {
worker = new Promise((resolve, reject) => {