diff --git a/backend/package.json b/backend/package.json index 0733dd0..6e3112d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.81", + "version": "2.14.82", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/processors/index.js b/backend/src/core/proxy-utils/processors/index.js index 3e3c2c0..fa2a8d4 100644 --- a/backend/src/core/proxy-utils/processors/index.js +++ b/backend/src/core/proxy-utils/processors/index.js @@ -8,6 +8,7 @@ import $ from '@/core/app'; import { hex_md5 } from '@/vendor/md5'; import { ProxyUtils } from '@/core/proxy-utils'; import env from '@/utils/env'; +import { getFlowHeaders, parseFlowHeaders, flowTransfer } from '@/utils/flow'; /** The rule "(name CONTAINS "🇨🇳") AND (port IN [80, 443])" can be expressed as follows: @@ -668,6 +669,7 @@ function removeFlag(str) { } function createDynamicFunction(name, script, $arguments) { + const flowUtils = { getFlowHeaders, parseFlowHeaders, flowTransfer }; if ($.env.isLoon) { return new Function( '$arguments', @@ -678,6 +680,7 @@ function createDynamicFunction(name, script, $arguments) { '$notification', 'ProxyUtils', 'scriptResourceCache', + 'flowUtils', `${script}\n return ${name}`, )( $arguments, @@ -691,6 +694,7 @@ function createDynamicFunction(name, script, $arguments) { $notification, ProxyUtils, scriptResourceCache, + flowUtils, ); } else { return new Function( @@ -699,7 +703,9 @@ function createDynamicFunction(name, script, $arguments) { 'lodash', 'ProxyUtils', 'scriptResourceCache', + 'flowUtils', + `${script}\n return ${name}`, - )($arguments, $, lodash, ProxyUtils, scriptResourceCache); + )($arguments, $, lodash, ProxyUtils, scriptResourceCache, flowUtils); } } diff --git a/backend/src/restful/subscriptions.js b/backend/src/restful/subscriptions.js index 4ad88c1..17d4f53 100644 --- a/backend/src/restful/subscriptions.js +++ b/backend/src/restful/subscriptions.js @@ -6,7 +6,7 @@ import { } from './errors'; import { deleteByName, findByName, updateByName } from '@/utils/database'; import { SUBS_KEY, COLLECTIONS_KEY, ARTIFACTS_KEY } from '@/constants'; -import { getFlowHeaders } from '@/utils/flow'; +import { getFlowHeaders, parseFlowHeaders } from '@/utils/flow'; import { success, failed } from './response'; import $ from '@/core/app'; @@ -68,20 +68,7 @@ async function getFlowInfo(req, res) { return; } - // unit is KB - const uploadMatch = flowHeaders.match(/upload=(-?)(\d+)/); - const upload = Number(uploadMatch[1] + uploadMatch[2]); - - const downloadMatch = flowHeaders.match(/download=(-?)(\d+)/); - const download = Number(downloadMatch[1] + downloadMatch[2]); - - const total = Number(flowHeaders.match(/total=(\d+)/)[1]); - - // optional expire timestamp - const match = flowHeaders.match(/expire=(\d+)/); - const expires = match ? Number(match[1]) : undefined; - - success(res, { expires, total, usage: { upload, download } }); + success(res, parseFlowHeaders(flowHeaders)); } catch (err) { failed( res, diff --git a/backend/src/utils/flow.js b/backend/src/utils/flow.js index 606aa24..b0cc8b9 100644 --- a/backend/src/utils/flow.js +++ b/backend/src/utils/flow.js @@ -13,3 +13,28 @@ export async function getFlowHeaders(url) { )[0]; return headers[subkey]; } +export function parseFlowHeaders(flowHeaders) { + if (!flowHeaders) return; + // unit is KB + const uploadMatch = flowHeaders.match(/upload=(-?)(\d+)/); + const upload = Number(uploadMatch[1] + uploadMatch[2]); + + const downloadMatch = flowHeaders.match(/download=(-?)(\d+)/); + const download = Number(downloadMatch[1] + downloadMatch[2]); + + const total = Number(flowHeaders.match(/total=(\d+)/)[1]); + + // optional expire timestamp + const match = flowHeaders.match(/expire=(\d+)/); + const expires = match ? Number(match[1]) : undefined; + + return { expires, total, usage: { upload, download } }; +} +export function flowTransfer(flow, unit = 'B') { + const unitList = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']; + let unitIndex = unitList.indexOf(unit); + + return flow < 1024 + ? { value: flow.toFixed(1), unit: unit } + : flowTransfer(flow / 1024, unitList[++unitIndex]); +}