From 99d058bcf148acf0bb03a855561be6998a5219c6 Mon Sep 17 00:00:00 2001 From: xream Date: Sun, 2 Jun 2024 16:03:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20flowUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 +- backend/src/restful/download.js | 2 + backend/src/restful/subscriptions.js | 1 + backend/src/utils/download.js | 1 + backend/src/utils/flow.js | 110 +++++++++++++++------------ 5 files changed, 68 insertions(+), 48 deletions(-) diff --git a/backend/package.json b/backend/package.json index 422dd82ad..74ed57142 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.329", + "version": "2.14.330", "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 d002f545c..c567d656a 100644 --- a/backend/src/restful/download.js +++ b/backend/src/restful/download.js @@ -156,6 +156,7 @@ async function downloadSubscription(req, res) { $arguments.flowUserAgent, undefined, sub.proxy, + $arguments.flowUrl, ); if (flowInfo) { res.set('subscription-userinfo', flowInfo); @@ -314,6 +315,7 @@ async function downloadCollection(req, res) { $arguments.flowUserAgent, undefined, sub.proxy, + $arguments.flowUrl, ); if (flowInfo) { res.set('subscription-userinfo', flowInfo); diff --git a/backend/src/restful/subscriptions.js b/backend/src/restful/subscriptions.js index 984f07a31..0324ee383 100644 --- a/backend/src/restful/subscriptions.js +++ b/backend/src/restful/subscriptions.js @@ -118,6 +118,7 @@ async function getFlowInfo(req, res) { $arguments.flowUserAgent, undefined, sub.proxy, + $arguments.flowUrl, ); if (!flowHeaders) { failed( diff --git a/backend/src/utils/download.js b/backend/src/utils/download.js index 4cc68955c..771ae0bf7 100644 --- a/backend/src/utils/download.js +++ b/backend/src/utils/download.js @@ -217,6 +217,7 @@ export default async function download( $arguments.flowUserAgent, undefined, proxy, + $arguments.flowUrl, ), ), ); diff --git a/backend/src/utils/flow.js b/backend/src/utils/flow.js index a35fb1eea..18fb8d9b7 100644 --- a/backend/src/utils/flow.js +++ b/backend/src/utils/flow.js @@ -10,8 +10,8 @@ export function getFlowField(headers) { )[0]; return headers[subkey]; } -export async function getFlowHeaders(rawUrl, ua, timeout, proxy) { - let url = rawUrl; +export async function getFlowHeaders(rawUrl, ua, timeout, proxy, flowUrl) { + let url = flowUrl || rawUrl; let $arguments = {}; const rawArgs = url.split('#'); url = url.split('#')[0]; @@ -48,60 +48,76 @@ export async function getFlowHeaders(rawUrl, ua, timeout, proxy) { 'Quantumult%20X/1.0.30 (iPhone14,2; iOS 15.6)'; const requestTimeout = timeout || defaultTimeout; const http = HTTP(); - try { + if (flowUrl) { $.info( - `使用 HEAD 方法获取流量信息: ${url}, User-Agent: ${ + `使用 GET 方法从响应体获取流量信息: ${flowUrl}, User-Agent: ${ userAgent || '' }`, ); - const { headers } = await http.head({ - url: url - .split(/[\r\n]+/) - .map((i) => i.trim()) - .filter((i) => i.length)[0], + const { body } = await http.get({ + url: flowUrl, 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) : {}), }); - flowInfo = getFlowField(headers); - } catch (e) { - $.error( - `使用 HEAD 方法获取流量信息失败: ${url}, User-Agent: ${ - userAgent || '' - }: ${e.message ?? e}`, - ); - } - if (!flowInfo) { - $.info( - `使用 GET 方法获取流量信息: ${url}, User-Agent: ${ - userAgent || '' - }`, - ); - const { headers } = await http.get({ - url: url - .split(/[\r\n]+/) - .map((i) => i.trim()) - .filter((i) => i.length)[0], - headers: { - 'User-Agent': userAgent, - }, - timeout: requestTimeout, - }); - flowInfo = getFlowField(headers); + flowInfo = body; + } else { + try { + $.info( + `使用 HEAD 方法从响应头获取流量信息: ${url}, User-Agent: ${ + userAgent || '' + }`, + ); + const { headers } = await http.head({ + url: url + .split(/[\r\n]+/) + .map((i) => i.trim()) + .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) : {}), + }); + flowInfo = getFlowField(headers); + } catch (e) { + $.error( + `使用 HEAD 方法从响应头获取流量信息失败: ${url}, User-Agent: ${ + userAgent || '' + }: ${e.message ?? e}`, + ); + } + if (!flowInfo) { + $.info( + `使用 GET 方法获取流量信息: ${url}, User-Agent: ${ + userAgent || '' + }`, + ); + const { headers } = await http.get({ + url: url + .split(/[\r\n]+/) + .map((i) => i.trim()) + .filter((i) => i.length)[0], + headers: { + 'User-Agent': userAgent, + }, + timeout: requestTimeout, + }); + flowInfo = getFlowField(headers); + } } if (flowInfo) { headersResourceCache.set(url, flowInfo);