diff --git a/backend/package.json b/backend/package.json index c0d80ec..ecb825b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.249", + "version": "2.14.251", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/restful/download.js b/backend/src/restful/download.js index 2fce1a7..45bd8e9 100644 --- a/backend/src/restful/download.js +++ b/backend/src/restful/download.js @@ -111,7 +111,12 @@ async function downloadSubscription(req, res) { } if (!$arguments.noFlow) { // forward flow headers - const flowInfo = await getFlowHeaders(url); + const flowInfo = await getFlowHeaders( + url, + undefined, + undefined, + sub.proxy, + ); if (flowInfo) { res.set('subscription-userinfo', flowInfo); } @@ -243,7 +248,12 @@ async function downloadCollection(req, res) { } } if (!$arguments.noFlow) { - const flowInfo = await getFlowHeaders(url); + const flowInfo = await getFlowHeaders( + url, + undefined, + undefined, + sub.proxy, + ); if (flowInfo) { res.set('subscription-userinfo', flowInfo); } diff --git a/backend/src/restful/preview.js b/backend/src/restful/preview.js index 77f9f6b..6745782 100644 --- a/backend/src/restful/preview.js +++ b/backend/src/restful/preview.js @@ -109,7 +109,12 @@ async function compareSub(req, res) { .filter((i) => i.length) .map(async (url) => { try { - return await download(url, sub.ua); + return await download( + url, + sub.ua, + undefined, + sub.proxy, + ); } catch (err) { errors[url] = err; $.error( @@ -195,7 +200,12 @@ async function compareCollection(req, res) { .filter((i) => i.length) .map(async (url) => { try { - return await download(url, sub.ua); + return await download( + url, + sub.ua, + undefined, + sub.proxy, + ); } catch (err) { errors[url] = err; $.error( diff --git a/backend/src/restful/subscriptions.js b/backend/src/restful/subscriptions.js index af3d367..1a5b3a6 100644 --- a/backend/src/restful/subscriptions.js +++ b/backend/src/restful/subscriptions.js @@ -113,7 +113,12 @@ async function getFlowInfo(req, res) { }), }); } else { - const flowHeaders = await getFlowHeaders(url); + const flowHeaders = await getFlowHeaders( + url, + undefined, + undefined, + sub.proxy, + ); if (!flowHeaders) { failed( res, diff --git a/backend/src/restful/sync.js b/backend/src/restful/sync.js index fc98604..e462c5e 100644 --- a/backend/src/restful/sync.js +++ b/backend/src/restful/sync.js @@ -62,7 +62,12 @@ async function produceArtifact({ .filter((i) => i.length) .map(async (url) => { try { - return await download(url, ua || sub.ua); + return await download( + url, + ua || sub.ua, + undefined, + sub.proxy, + ); } catch (err) { errors[url] = err; $.error( @@ -102,7 +107,12 @@ async function produceArtifact({ .filter((i) => i.length) .map(async (url) => { try { - return await download(url, ua || sub.ua); + return await download( + url, + ua || sub.ua, + undefined, + sub.proxy, + ); } catch (err) { errors[url] = err; $.error( @@ -198,7 +208,12 @@ async function produceArtifact({ .filter((i) => i.length) .map(async (url) => { try { - return await download(url, sub.ua); + return await download( + url, + sub.ua, + undefined, + sub.proxy, + ); } catch (err) { errors[url] = err; $.error( diff --git a/backend/src/utils/download.js b/backend/src/utils/download.js index 600f257..6407cb0 100644 --- a/backend/src/utils/download.js +++ b/backend/src/utils/download.js @@ -1,6 +1,7 @@ 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 { @@ -13,7 +14,7 @@ import $ from '@/core/app'; const tasks = new Map(); -export default async function download(rawUrl, ua, timeout) { +export default async function download(rawUrl, ua, timeout, proxy) { let $arguments = {}; let url = rawUrl.replace(/#noFlow$/, ''); const rawArgs = url.split('#'); @@ -52,7 +53,7 @@ export default async function download(rawUrl, ua, timeout) { // return item.content; // } - const { isNode } = ENV(); + const { isNode, isStash } = ENV(); const { defaultUserAgent, defaultTimeout, cacheThreshold } = $.read(SETTINGS_KEY); const userAgent = ua || defaultUserAgent || 'clash.meta'; @@ -65,6 +66,8 @@ export default async function download(rawUrl, ua, timeout) { const http = HTTP({ headers: { 'User-Agent': userAgent, + 'X-Stash-Selected-Proxy': + isStash && proxy ? encodeURIComponent(proxy) : undefined, }, timeout: requestTimeout, }); @@ -78,10 +81,14 @@ export default async function download(rawUrl, ua, timeout) { result = cached; } else { $.info( - `Downloading...\nUser-Agent: ${userAgent}\nTimeout: ${requestTimeout}\nURL: ${url}`, + `Downloading...\nUser-Agent: ${userAgent}\nTimeout: ${requestTimeout}\nProxy: ${proxy}\nURL: ${url}`, ); try { - const { body, headers } = await http.get(url); + const { body, headers } = await http.get({ + url, + proxy, + ...getPolicyDescriptor(proxy), + }); if (headers) { const flowInfo = getFlowField(headers); @@ -116,7 +123,11 @@ export default async function download(rawUrl, ua, timeout) { // 检查订阅有效性 if ($arguments?.validCheck) { - await validCheck(parseFlowHeaders(await getFlowHeaders(url))); + await validCheck( + parseFlowHeaders( + await getFlowHeaders(url, undefined, undefined, proxy), + ), + ); } if (!isNode) { diff --git a/backend/src/utils/flow.js b/backend/src/utils/flow.js index b7f259d..9d1daa4 100644 --- a/backend/src/utils/flow.js +++ b/backend/src/utils/flow.js @@ -1,5 +1,6 @@ import { SETTINGS_KEY } from '@/constants'; -import { HTTP } from '@/vendor/open-api'; +import { HTTP, ENV } from '@/vendor/open-api'; +import { getPolicyDescriptor } from '@/utils'; import $ from '@/core/app'; import headersResourceCache from '@/utils/headers-resource-cache'; @@ -9,7 +10,7 @@ export function getFlowField(headers) { )[0]; return headers[subkey]; } -export async function getFlowHeaders(rawUrl, ua, timeout) { +export async function getFlowHeaders(rawUrl, ua, timeout, proxy) { let url = rawUrl; let $arguments = {}; const rawArgs = url.split('#'); @@ -33,6 +34,7 @@ export async function getFlowHeaders(rawUrl, ua, timeout) { if ($arguments?.noFlow) { return; } + const { isStash } = ENV(); const cached = headersResourceCache.get(url); let flowInfo; if (!$arguments?.noCache && cached) { @@ -55,8 +57,14 @@ export async function getFlowHeaders(rawUrl, ua, timeout) { .filter((i) => i.length)[0], headers: { 'User-Agent': userAgent, + 'X-Stash-Selected-Proxy': + isStash && proxy + ? encodeURIComponent(proxy) + : undefined, }, timeout: requestTimeout, + proxy, + ...getPolicyDescriptor(proxy), }); flowInfo = getFlowField(headers); } catch (e) { @@ -178,7 +186,7 @@ export function getRmainingDays(opt = {}) { return daysDiff; } else { - if (!resetDay) throw new Error('未提供月重置日 resetDay'); + if (!resetDay) return; resetDay = parseInt(resetDay); if (isNaN(resetDay) || resetDay <= 0 || resetDay > 31) throw new Error('月重置日应为 1-31 之间的整数'); diff --git a/backend/src/utils/index.js b/backend/src/utils/index.js index d49ae7b..6380b72 100644 --- a/backend/src/utils/index.js +++ b/backend/src/utils/index.js @@ -35,6 +35,17 @@ 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)) @@ -91,4 +102,5 @@ export { isPresent, getIfPresent, utf8ArrayToStr, + getPolicyDescriptor, };