mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-04-20 04:39:31 +08:00
feat: 规范化 subscription-userinfo
This commit is contained in:
parent
6efb19c856
commit
41034ceb46
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.16.57",
|
"version": "2.16.58",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
validCheck,
|
validCheck,
|
||||||
flowTransfer,
|
flowTransfer,
|
||||||
getRmainingDays,
|
getRmainingDays,
|
||||||
|
normalizeFlowHeader,
|
||||||
} from '@/utils/flow';
|
} from '@/utils/flow';
|
||||||
|
|
||||||
function isObject(item) {
|
function isObject(item) {
|
||||||
@ -1083,6 +1084,7 @@ function createDynamicFunction(name, script, $arguments, $options) {
|
|||||||
flowTransfer,
|
flowTransfer,
|
||||||
validCheck,
|
validCheck,
|
||||||
getRmainingDays,
|
getRmainingDays,
|
||||||
|
normalizeFlowHeader,
|
||||||
};
|
};
|
||||||
if ($.env.isLoon) {
|
if ($.env.isLoon) {
|
||||||
return new Function(
|
return new Function(
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
import { ProxyUtils } from '@/core/proxy-utils';
|
import { ProxyUtils } from '@/core/proxy-utils';
|
||||||
import { COLLECTIONS_KEY, SUBS_KEY } from '@/constants';
|
import { COLLECTIONS_KEY, SUBS_KEY } from '@/constants';
|
||||||
import { findByName } from '@/utils/database';
|
import { findByName } from '@/utils/database';
|
||||||
import { getFlowHeaders } from '@/utils/flow';
|
import { getFlowHeaders, normalizeFlowHeader } from '@/utils/flow';
|
||||||
import $ from '@/core/app';
|
import $ from '@/core/app';
|
||||||
import { failed } from '@/restful/response';
|
import { failed } from '@/restful/response';
|
||||||
import { InternalServerError, ResourceNotFoundError } from '@/restful/errors';
|
import { InternalServerError, ResourceNotFoundError } from '@/restful/errors';
|
||||||
@ -259,7 +259,10 @@ async function downloadSubscription(req, res) {
|
|||||||
$arguments.flowUrl,
|
$arguments.flowUrl,
|
||||||
);
|
);
|
||||||
if (flowInfo) {
|
if (flowInfo) {
|
||||||
res.set('subscription-userinfo', flowInfo);
|
res.set(
|
||||||
|
'subscription-userinfo',
|
||||||
|
normalizeFlowHeader(flowInfo),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -293,10 +296,9 @@ async function downloadSubscription(req, res) {
|
|||||||
}
|
}
|
||||||
res.set(
|
res.set(
|
||||||
'subscription-userinfo',
|
'subscription-userinfo',
|
||||||
[subUserInfo, flowInfo]
|
normalizeFlowHeader(
|
||||||
.filter((i) => i)
|
[subUserInfo, flowInfo].filter((i) => i).join(';'),
|
||||||
.join('; ')
|
),
|
||||||
.replace(/\s*;\s*;\s*/g, ';'),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,7 +558,7 @@ async function downloadCollection(req, res) {
|
|||||||
if (subUserInfo) {
|
if (subUserInfo) {
|
||||||
res.set(
|
res.set(
|
||||||
'subscription-userinfo',
|
'subscription-userinfo',
|
||||||
subUserInfo.replace(/\s*;\s*;\s*/g, ';'),
|
normalizeFlowHeader(subUserInfo),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (platform === 'JSON') {
|
if (platform === 'JSON') {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { deleteByName, findByName, updateByName } from '@/utils/database';
|
import { deleteByName, findByName, updateByName } from '@/utils/database';
|
||||||
import { getFlowHeaders } from '@/utils/flow';
|
import { getFlowHeaders, normalizeFlowHeader } from '@/utils/flow';
|
||||||
import { FILES_KEY } from '@/constants';
|
import { FILES_KEY } from '@/constants';
|
||||||
import { failed, success } from '@/restful/response';
|
import { failed, success } from '@/restful/response';
|
||||||
import $ from '@/core/app';
|
import $ from '@/core/app';
|
||||||
@ -148,7 +148,7 @@ async function getFile(req, res) {
|
|||||||
if (flowInfo) {
|
if (flowInfo) {
|
||||||
res.set(
|
res.set(
|
||||||
'subscription-userinfo',
|
'subscription-userinfo',
|
||||||
flowInfo.replace(/\s*;\s*;\s*/g, ';'),
|
normalizeFlowHeader(flowInfo),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,3 +313,41 @@ export function getRmainingDays(opt = {}) {
|
|||||||
$.error(`getRmainingDays failed: ${e.message ?? e}`);
|
$.error(`getRmainingDays failed: ${e.message ?? e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeFlowHeader(flowHeaders) {
|
||||||
|
try {
|
||||||
|
// 使用 Map 保持顺序并处理重复键
|
||||||
|
const kvMap = new Map();
|
||||||
|
|
||||||
|
flowHeaders
|
||||||
|
.split(';')
|
||||||
|
.map((p) => p.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
.forEach((pair) => {
|
||||||
|
const eqIndex = pair.indexOf('=');
|
||||||
|
if (eqIndex === -1) return;
|
||||||
|
|
||||||
|
const key = pair.slice(0, eqIndex).trim();
|
||||||
|
const encodedValue = pair.slice(eqIndex + 1).trim();
|
||||||
|
|
||||||
|
// 只保留第一个出现的 key
|
||||||
|
if (!kvMap.has(key)) {
|
||||||
|
try {
|
||||||
|
// 解码 URI 组件并保留原始值作为 fallback
|
||||||
|
const decodedValue = decodeURIComponent(encodedValue);
|
||||||
|
kvMap.set(key, decodedValue);
|
||||||
|
} catch (e) {
|
||||||
|
kvMap.set(key, encodedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 拼接标准化字符串
|
||||||
|
return Array.from(kvMap.entries())
|
||||||
|
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`) // 重新编码保持兼容性
|
||||||
|
.join('; ');
|
||||||
|
} catch (e) {
|
||||||
|
$.error(`normalizeFlowHeader failed: ${e.message ?? e}`);
|
||||||
|
return flowHeaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user