Skip to content

Commit dc778b9

Browse files
committed
feat: 订阅流量信息还原为 profile-web-page-url 响应头, 避免某些客户端出现异常
1 parent 6dc7cc4 commit dc778b9

4 files changed

Lines changed: 77 additions & 24 deletions

File tree

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.20.69",
3+
"version": "2.20.71",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"scripts": {

backend/src/restful/download.js

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,19 @@ async function downloadSubscription(req, res) {
261261
$arguments.flowUrl,
262262
);
263263
if (flowInfo) {
264-
res.set(
265-
'subscription-userinfo',
266-
normalizeFlowHeader(flowInfo),
267-
);
264+
const headers = normalizeFlowHeader(flowInfo, true);
265+
if (headers?.['subscription-userinfo']) {
266+
res.set(
267+
'subscription-userinfo',
268+
headers['subscription-userinfo'],
269+
);
270+
}
271+
if (headers?.['profile-web-page-url']) {
272+
res.set(
273+
'profile-web-page-url',
274+
headers['profile-web-page-url'],
275+
);
276+
}
268277
}
269278
}
270279
} catch (err) {
@@ -296,12 +305,23 @@ async function downloadSubscription(req, res) {
296305
} else {
297306
subUserInfo = sub.subUserinfo;
298307
}
299-
res.set(
300-
'subscription-userinfo',
301-
normalizeFlowHeader(
302-
[subUserInfo, flowInfo].filter((i) => i).join(';'),
303-
),
308+
309+
const headers = normalizeFlowHeader(
310+
[subUserInfo, flowInfo].filter((i) => i).join(';'),
311+
true,
304312
);
313+
if (headers?.['subscription-userinfo']) {
314+
res.set(
315+
'subscription-userinfo',
316+
headers['subscription-userinfo'],
317+
);
318+
}
319+
if (headers?.['profile-web-page-url']) {
320+
res.set(
321+
'profile-web-page-url',
322+
headers['profile-web-page-url'],
323+
);
324+
}
305325
}
306326

307327
if (platform === 'JSON') {
@@ -573,10 +593,19 @@ async function downloadCollection(req, res) {
573593
.filter((i) => i)
574594
.join('; ');
575595
if (subUserInfo) {
576-
res.set(
577-
'subscription-userinfo',
578-
normalizeFlowHeader(subUserInfo),
579-
);
596+
const headers = normalizeFlowHeader(subUserInfo, true);
597+
if (headers?.['subscription-userinfo']) {
598+
res.set(
599+
'subscription-userinfo',
600+
headers['subscription-userinfo'],
601+
);
602+
}
603+
if (headers?.['profile-web-page-url']) {
604+
res.set(
605+
'profile-web-page-url',
606+
headers['profile-web-page-url'],
607+
);
608+
}
580609
}
581610
if (platform === 'JSON') {
582611
if (resultFormat === 'nezha') {

backend/src/restful/file.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,19 @@ async function getFile(req, res) {
156156
proxy || file.proxy,
157157
);
158158
if (flowInfo) {
159-
res.set(
160-
'subscription-userinfo',
161-
normalizeFlowHeader(flowInfo),
162-
);
159+
const headers = normalizeFlowHeader(flowInfo, true);
160+
if (headers?.['subscription-userinfo']) {
161+
res.set(
162+
'subscription-userinfo',
163+
headers['subscription-userinfo'],
164+
);
165+
}
166+
if (headers?.['profile-web-page-url']) {
167+
res.set(
168+
'profile-web-page-url',
169+
headers['profile-web-page-url'],
170+
);
171+
}
163172
}
164173
}
165174
} catch (err) {

backend/src/utils/flow.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ export function getRmainingDays(opt = {}) {
318318
}
319319
}
320320

321-
export function normalizeFlowHeader(flowHeaders) {
321+
export function normalizeFlowHeader(flowHeaders, splitHeaders) {
322322
try {
323323
// 使用 Map 保持顺序并处理重复键
324324
const kvMap = new Map();
@@ -366,11 +366,26 @@ export function normalizeFlowHeader(flowHeaders) {
366366
}
367367
}
368368
});
369-
370-
// 拼接标准化字符串
371-
return Array.from(kvMap.entries())
372-
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`) // 重新编码保持兼容性
373-
.join('; ');
369+
const subscriptionUserinfo = {};
370+
const headers = {
371+
'subscription-userinfo': '',
372+
'profile-web-page-url': '',
373+
};
374+
kvMap.forEach((v, k) => {
375+
if (splitHeaders && k === 'app_url') {
376+
headers['profile-web-page-url'] = v;
377+
} else {
378+
subscriptionUserinfo[k] = v;
379+
}
380+
});
381+
if (Object.keys(subscriptionUserinfo).length > 0) {
382+
headers['subscription-userinfo'] = Object.entries(
383+
subscriptionUserinfo,
384+
)
385+
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
386+
.join('; ');
387+
}
388+
return splitHeaders ? headers : headers['subscription-userinfo'];
374389
} catch (e) {
375390
$.error(`normalizeFlowHeader failed: ${e.message ?? e}`);
376391
return flowHeaders;

0 commit comments

Comments
 (0)