bug fixed

This commit is contained in:
Peng-YM 2020-09-01 17:56:24 +08:00
parent 8fc5e58276
commit 2d6aa1ef1a
5 changed files with 2875 additions and 2877 deletions

View File

@ -22,8 +22,9 @@
<list default="true" id="8b97a098-48b2-4e64-a9ef-522fe2d30b52" name="Default Changelist" comment=""> <list default="true" id="8b97a098-48b2-4e64-a9ef-522fe2d30b52" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/sub-store.js" beforeDir="false" afterPath="$PROJECT_DIR$/sub-store.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/sub-store.js" beforeDir="false" afterPath="$PROJECT_DIR$/sub-store.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../web/src/components/SortOperator.vue" beforeDir="false" afterPath="$PROJECT_DIR$/../web/src/components/SortOperator.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/../web/src/components/ProxyList.vue" beforeDir="false" afterPath="$PROJECT_DIR$/../web/src/components/ProxyList.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../web/src/config.js" beforeDir="false" afterPath="$PROJECT_DIR$/../web/src/config.js" afterDir="false" /> <change beforePath="$PROJECT_DIR$/../web/src/config.js" beforeDir="false" afterPath="$PROJECT_DIR$/../web/src/config.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../web/src/views/Subscription.vue" beforeDir="false" afterPath="$PROJECT_DIR$/../web/src/views/Subscription.vue" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -93,6 +94,7 @@
<workItem from="1598900239005" duration="4742000" /> <workItem from="1598900239005" duration="4742000" />
<workItem from="1598931009084" duration="2069000" /> <workItem from="1598931009084" duration="2069000" />
<workItem from="1598946261983" duration="463000" /> <workItem from="1598946261983" duration="463000" />
<workItem from="1598948545209" duration="3969000" />
</task> </task>
<servers /> <servers />
</component> </component>

View File

@ -9,8 +9,9 @@
* 3. 订阅拆分组合 * 3. 订阅拆分组合
*/ */
const $ = API("sub-store", true); const $ = API("sub-store", true);
const $code = new Base64Code(); const $app = express();
$.http = HTTP("", {
$.http = HTTP({
headers: { headers: {
"User-Agent": "Quantumult", "User-Agent": "Quantumult",
}, },
@ -18,6 +19,26 @@ $.http = HTTP("", {
// Constants // Constants
const SUBS_KEY = "subs"; const SUBS_KEY = "subs";
const COLLECTIONS_KEY = "collections"; const COLLECTIONS_KEY = "collections";
const AVAILABLE_FILTERS = {
"Keyword Filter": KeywordFilter,
"Useless Filter": UselessFilter,
"Region Filter": RegionFilter,
"Regex Filter": RegexFilter,
"Type Filter": TypeFilter,
"Script Filter": ScriptFilter,
};
const AVAILABLE_OPERATORS = {
"Set Property Operator": SetPropertyOperator,
"Flag Operator": FlagOperator,
"Sort Operator": SortOperator,
"Keyword Sort Operator": KeywordSortOperator,
"Keyword Rename Operator": KeywordRenameOperator,
"Keyword Delete Operator": KeywordDeleteOperator,
"Regex Rename Operator": RegexRenameOperator,
"Regex Delete Operator": RegexDeleteOperator,
"Script Operator": ScriptOperator,
};
// SOME INITIALIZATIONS // SOME INITIALIZATIONS
if (!$.read(SUBS_KEY)) $.write({}, SUBS_KEY); if (!$.read(SUBS_KEY)) $.write({}, SUBS_KEY);
@ -25,20 +46,19 @@ if (!$.read(COLLECTIONS_KEY)) $.write({}, COLLECTIONS_KEY);
// BACKEND API // BACKEND API
$.log("Initializing Express..."); $.log("Initializing Express...");
const $app = express();
// download // download
$app.get("/download/collection/:name", downloadCollection); $app.get("/download/collection/:name", downloadCollection);
$app.get("/download/:name", downloadSub); $app.get("/download/:name", downloadSub);
// refresh
$app.post("/api/refresh", refreshResource);
// subscriptions // subscriptions
$app.route("/api/sub/:name").get(getSub).patch(updateSub).delete(deleteSub); $app.route("/api/sub/:name").get(getSub).patch(updateSub).delete(deleteSub);
$app.route("/api/sub").get(getAllSubs).post(newSub).delete(deleteAllSubs); $app.route("/api/sub").get(getAllSubs).post(newSub).delete(deleteAllSubs);
// refresh
$app.post("/api/refresh", refreshResource);
// collections // collections
$app $app
.route("/api/collection/:name") .route("/api/collection/:name")
@ -56,42 +76,14 @@ $app.all("/", async (req, res) => {
res.send("Hello from Sub-Store! Made with ❤️ by Peng-YM."); res.send("Hello from Sub-Store! Made with ❤️ by Peng-YM.");
}); });
$app.start();
$.log("Express initialized"); $.log("Express initialized");
$app.start();
// SOME CONSTANTS
var DEFAULT_SUPPORTED_PLATFORMS = {
QX: true,
Loon: true,
Surge: true,
Raw: true,
};
var AVAILABLE_FILTERS = {
"Keyword Filter": KeywordFilter,
"Useless Filter": UselessFilter,
"Region Filter": RegionFilter,
"Regex Filter": RegexFilter,
"Type Filter": TypeFilter,
"Script Filter": ScriptFilter,
};
var AVAILABLE_OPERATORS = {
"Set Property Operator": SetPropertyOperator,
"Flag Operator": FlagOperator,
"Sort Operator": SortOperator,
"Keyword Sort Operator": KeywordSortOperator,
"Keyword Rename Operator": KeywordRenameOperator,
"Keyword Delete Operator": KeywordDeleteOperator,
"Regex Rename Operator": RegexRenameOperator,
"Regex Delete Operator": RegexDeleteOperator,
"Script Operator": ScriptOperator,
};
/**************************** API -- Subscriptions ***************************************/ /**************************** API -- Subscriptions ***************************************/
// refresh resource // refresh resource
async function refreshResource(req, res) { async function refreshResource(req, res) {
const { url } = req.body; const Base64 = new Base64Code();
const {url} = req.body;
const raw = await $.http const raw = await $.http
.get(url) .get(url)
.then((resp) => resp.body) .then((resp) => resp.body)
@ -101,7 +93,7 @@ async function refreshResource(req, res) {
message: `Cannot refresh remote resource: ${url}\n Reason: ${err}`, message: `Cannot refresh remote resource: ${url}\n Reason: ${err}`,
}); });
}); });
$.write(raw, `#${$code.safeEncode(url)}`); $.write(raw, `#${Base64.safeEncode(url)}`);
res.json({ res.json({
status: "success", status: "success",
}); });
@ -109,7 +101,7 @@ async function refreshResource(req, res) {
// download subscription, for APP only // download subscription, for APP only
async function downloadSub(req, res) { async function downloadSub(req, res) {
const { name } = req.params; const {name} = req.params;
const platform = req.query.target || getPlatformFromHeaders(req.headers); const platform = req.query.target || getPlatformFromHeaders(req.headers);
const allSubs = $.read(SUBS_KEY); const allSubs = $.read(SUBS_KEY);
if (allSubs[name]) { if (allSubs[name]) {
@ -133,7 +125,7 @@ async function downloadSub(req, res) {
async function parseSub(sub, platform) { async function parseSub(sub, platform) {
let raw; let raw;
const key = $code.safeEncode(sub.url); const key = new Base64Code().safeEncode(sub.url);
if (platform === "Raw") { if (platform === "Raw") {
const cache = $.read(`#${key}`); const cache = $.read(`#${key}`);
@ -221,7 +213,7 @@ async function parseSub(sub, platform) {
if (item.type.indexOf("Filter") !== -1) { if (item.type.indexOf("Filter") !== -1) {
const filter = AVAILABLE_FILTERS[item.type]; const filter = AVAILABLE_FILTERS[item.type];
if (filter) { if (filter) {
$filter.addFilters(filter(item.args)); $filter.setFilter(filter(item.args));
proxies = $filter.process(proxies); proxies = $filter.process(proxies);
$.log( $.log(
`Applying filter "${item.type}" with arguments:\n >>> ${ `Applying filter "${item.type}" with arguments:\n >>> ${
@ -232,7 +224,7 @@ async function parseSub(sub, platform) {
} else if (item.type.indexOf("Operator") !== -1) { } else if (item.type.indexOf("Operator") !== -1) {
const operator = AVAILABLE_OPERATORS[item.type]; const operator = AVAILABLE_OPERATORS[item.type];
if (operator) { if (operator) {
$operator.addOperators(operator(item.args)); $operator.setOperator(operator(item.args));
proxies = $operator.process(proxies); proxies = $operator.process(proxies);
$.log( $.log(
`Applying operator "${item.type}" with arguments: \n >>> ${ `Applying operator "${item.type}" with arguments: \n >>> ${
@ -294,7 +286,7 @@ function getFlowHeaders(headers, proxies) {
// Subscriptions // Subscriptions
async function getSub(req, res) { async function getSub(req, res) {
const { name } = req.params; const {name} = req.params;
const sub = $.read(SUBS_KEY)[name]; const sub = $.read(SUBS_KEY)[name];
if (sub) { if (sub) {
res.json({ res.json({
@ -335,7 +327,8 @@ async function newSub(req, res) {
} }
async function updateSub(req, res) { async function updateSub(req, res) {
const { name } = req.params; const {name} = req.params;
$.log(`Updating subscription: ${name}`);
let sub = req.body; let sub = req.body;
const allSubs = $.read(SUBS_KEY); const allSubs = $.read(SUBS_KEY);
if (allSubs[name]) { if (allSubs[name]) {
@ -373,7 +366,7 @@ async function updateSub(req, res) {
} }
async function deleteSub(req, res) { async function deleteSub(req, res) {
const { name } = req.params; const {name} = req.params;
// delete from subscriptions // delete from subscriptions
let allSubs = $.read(SUBS_KEY); let allSubs = $.read(SUBS_KEY);
delete allSubs[name]; delete allSubs[name];
@ -408,7 +401,7 @@ async function deleteAllSubs(req, res) {
// Collections // Collections
async function downloadCollection(req, res) { async function downloadCollection(req, res) {
const { name } = req.params; const {name} = req.params;
const collection = $.read(COLLECTIONS_KEY)[name]; const collection = $.read(COLLECTIONS_KEY)[name];
const platform = getPlatformFromHeaders(req.headers); const platform = getPlatformFromHeaders(req.headers);
if (collection) { if (collection) {
@ -435,7 +428,7 @@ async function downloadCollection(req, res) {
} }
async function getCollection(req, res) { async function getCollection(req, res) {
const { name } = req.params; const {name} = req.params;
const collection = $.read(COLLECTIONS_KEY)[name]; const collection = $.read(COLLECTIONS_KEY)[name];
if (collection) { if (collection) {
res.json({ res.json({
@ -476,7 +469,7 @@ async function newCollection(req, res) {
} }
async function updateCollection(req, res) { async function updateCollection(req, res) {
const { name } = req.params; const {name} = req.params;
let collection = req.body; let collection = req.body;
const allCol = $.read(COLLECTIONS_KEY); const allCol = $.read(COLLECTIONS_KEY);
if (allCol[name]) { if (allCol[name]) {
@ -501,7 +494,7 @@ async function updateCollection(req, res) {
} }
async function deleteCollection(req, res) { async function deleteCollection(req, res) {
const { name } = req.params; const {name} = req.params;
let allCol = $.read(COLLECTIONS_KEY); let allCol = $.read(COLLECTIONS_KEY);
delete allCol[name]; delete allCol[name];
$.write(allCol, COLLECTIONS_KEY); $.write(allCol, COLLECTIONS_KEY);
@ -551,7 +544,7 @@ function ProxyParser(targetPlatform) {
if (line.startsWith("#")) continue; // skip comments if (line.startsWith("#")) continue; // skip comments
let matched = false; let matched = false;
for (const p of parsers) { for (const p of parsers) {
const { patternTest, func } = p; const {patternTest, func} = p;
// some lines with weird format may produce errors! // some lines with weird format may produce errors!
let patternMatched; let patternMatched;
@ -666,54 +659,52 @@ function ProxyParser(targetPlatform) {
} }
function ProxyFilter() { function ProxyFilter() {
const filters = []; let filter;
function addFilters(...args) { function setFilter(arg) {
args.forEach((a) => filters.push(a)); filter = arg;
} }
// select proxies // select proxies
function process(proxies) { function process(proxies) {
let selected = FULL(proxies.length, true); let selected = FULL(proxies.length, true);
for (const filter of filters) {
try { try {
selected = AND(selected, filter.func(proxies)); selected = AND(selected, filter.func(proxies));
} catch (err) { } catch (err) {
console.log(`Cannot apply filter ${filter.name}\n Reason: ${err}`); console.log(`Cannot apply filter ${filter.name}\n Reason: ${err}`);
} }
}
return proxies.filter((_, i) => selected[i]); return proxies.filter((_, i) => selected[i]);
} }
return { return {
process, process,
addFilters, setFilter,
}; };
} }
function ProxyOperator() { function ProxyOperator() {
const operators = []; let operator;
function addOperators(...args) { function setOperator(arg) {
args.forEach((a) => operators.push(a)); operator = arg;
} }
// run all operators // run all operators
function process(proxies) { function process(proxies) {
let output = objClone(proxies); let output = objClone(proxies);
for (const op of operators) {
try { try {
const output_ = op.func(output); const output_ = operator.func(output);
if (output_) output = output_; if (output_) output = output_;
} catch (err) { } catch (err) {
// print log and skip this operator // print log and skip this operator
console.log(`ERROR: cannot apply operator ${op.name}! Reason: ${err}`); console.log(`ERROR: cannot apply operator ${op.name}! Reason: ${err}`);
} }
}
return output; return output;
} }
return { addOperators, process }; return {setOperator, process};
} }
/**************************** URI Format ***************************************/ /**************************** URI Format ***************************************/
@ -790,7 +781,7 @@ function URI_SS() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
// Parse URI SSR format, such as ssr://xxx // Parse URI SSR format, such as ssr://xxx
@ -852,7 +843,7 @@ function URI_SSR() {
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
// V2rayN URI VMess format // V2rayN URI VMess format
@ -934,7 +925,7 @@ function URI_VMess() {
return proxy; return proxy;
} }
}; };
return { patternTest, func }; return {patternTest, func};
} }
// Trojan URI format // Trojan URI format
@ -965,7 +956,7 @@ function URI_Trojan() {
supported, supported,
}; };
}; };
return { patternTest, func }; return {patternTest, func};
} }
/**************************** Clash ***************************************/ /**************************** Clash ***************************************/
@ -974,7 +965,7 @@ function Clash_All() {
return line.indexOf("{") !== -1; return line.indexOf("{") !== -1;
}; };
const func = (line) => JSON.parse(line); const func = (line) => JSON.parse(line);
return { patternTest, func }; return {patternTest, func};
} }
/**************************** Quantumult X ***************************************/ /**************************** Quantumult X ***************************************/
@ -1032,7 +1023,7 @@ function QX_SS() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function QX_SSR() { function QX_SSR() {
@ -1071,7 +1062,7 @@ function QX_SSR() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function QX_VMess() { function QX_VMess() {
@ -1107,7 +1098,7 @@ function QX_VMess() {
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function QX_Trojan() { function QX_Trojan() {
@ -1129,7 +1120,7 @@ function QX_Trojan() {
proxy.scert = !JSON.parse(params["tls-verification"] || "true"); proxy.scert = !JSON.parse(params["tls-verification"] || "true");
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function QX_Http() { function QX_Http() {
@ -1156,7 +1147,7 @@ function QX_Http() {
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function getQXParams(line) { function getQXParams(line) {
@ -1204,7 +1195,7 @@ function Loon_SS() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Loon_SSR() { function Loon_SSR() {
@ -1235,7 +1226,7 @@ function Loon_SSR() {
"obfs-param": params[8].match(/{(.*)}/)[1], "obfs-param": params[8].match(/{(.*)}/)[1],
}; };
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Loon_VMess() { function Loon_VMess() {
@ -1283,7 +1274,7 @@ function Loon_VMess() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Loon_Trojan() { function Loon_Trojan() {
@ -1314,7 +1305,7 @@ function Loon_Trojan() {
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Loon_Http() { function Loon_Http() {
@ -1345,7 +1336,7 @@ function Loon_Http() {
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
/**************************** Surge ***************************************/ /**************************** Surge ***************************************/
@ -1375,7 +1366,7 @@ function Surge_SS() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Surge_VMess() { function Surge_VMess() {
@ -1411,7 +1402,7 @@ function Surge_VMess() {
} }
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Surge_Trojan() { function Surge_Trojan() {
@ -1434,7 +1425,7 @@ function Surge_Trojan() {
}; };
}; };
return { patternTest, func }; return {patternTest, func};
} }
function Surge_Http() { function Surge_Http() {
@ -1461,7 +1452,7 @@ function Surge_Http() {
if (params.password !== "none") proxy.password = params.password; if (params.password !== "none") proxy.password = params.password;
return proxy; return proxy;
}; };
return { patternTest, func }; return {patternTest, func};
} }
function getSurgeParams(line) { function getSurgeParams(line) {
@ -1493,7 +1484,7 @@ function QX_Producer() {
obfs_opts = `,obfs=${proxy["plugin-opts"].mode},obfs-host=${proxy["plugin-opts"].host}`; obfs_opts = `,obfs=${proxy["plugin-opts"].mode},obfs-host=${proxy["plugin-opts"].host}`;
} }
if (proxy.plugin === "v2ray-plugin") { if (proxy.plugin === "v2ray-plugin") {
const { tls, host, path } = proxy["plugin-opts"]; const {tls, host, path} = proxy["plugin-opts"];
obfs_opts = `,obfs=${tls ? "wss" : "ws"},obfs-host=${host}${ obfs_opts = `,obfs=${tls ? "wss" : "ws"},obfs-host=${host}${
path ? ",obfs-uri=" + path : "" path ? ",obfs-uri=" + path : ""
}`; }`;
@ -1572,7 +1563,7 @@ function QX_Producer() {
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}` `Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
); );
}; };
return { targetPlatform, output }; return {targetPlatform, output};
} }
function Loon_Producer() { function Loon_Producer() {
@ -1584,7 +1575,7 @@ function Loon_Producer() {
obfs_opts = ",,"; obfs_opts = ",,";
if (proxy.plugin) { if (proxy.plugin) {
if (proxy.plugin === "obfs") { if (proxy.plugin === "obfs") {
const { mode, host } = proxy["plugin-opts"]; const {mode, host} = proxy["plugin-opts"];
obfs_opts = `,${mode},${host}`; obfs_opts = `,${mode},${host}`;
} else { } else {
throw new Error( throw new Error(
@ -1629,7 +1620,7 @@ function Loon_Producer() {
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}` `Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
); );
}; };
return { targetPlatform, output }; return {targetPlatform, output};
} }
function Surge_Producer() { function Surge_Producer() {
@ -1688,7 +1679,7 @@ function Surge_Producer() {
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}` `Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
); );
}; };
return { targetPlatform, output }; return {targetPlatform, output};
} }
function Raw_Producer() { function Raw_Producer() {
@ -1696,7 +1687,7 @@ function Raw_Producer() {
const output = (proxy) => { const output = (proxy) => {
return JSON.stringify(proxy); return JSON.stringify(proxy);
}; };
return { targetPlatform, output }; return {targetPlatform, output};
} }
/**************************** Operators ***************************************/ /**************************** Operators ***************************************/
@ -1719,10 +1710,10 @@ function FlagOperator(add = true) {
name: "Flag Operator", name: "Flag Operator",
func: (proxies) => { func: (proxies) => {
return proxies.map((proxy) => { return proxies.map((proxy) => {
if (!add) if (!add) {
// no flag // no flag
proxy.name = removeFlag(proxy.name); proxy.name = removeFlag(proxy.name);
else { } else {
// get flag // get flag
const newFlag = getFlag(proxy.name); const newFlag = getFlag(proxy.name);
// remove old flag // remove old flag
@ -1793,7 +1784,7 @@ function KeywordRenameOperator(keywords) {
name: "Keyword Rename Operator", name: "Keyword Rename Operator",
func: (proxies) => { func: (proxies) => {
return proxies.map((proxy) => { return proxies.map((proxy) => {
for (const { old, now } of keywords) { for (const {old, now} of keywords) {
proxy.name = proxy.name.replace(old, now).trim(); proxy.name = proxy.name.replace(old, now).trim();
} }
return proxy; return proxy;
@ -1809,7 +1800,7 @@ function RegexRenameOperator(regex) {
name: "Regex Rename Operator", name: "Regex Rename Operator",
func: (proxies) => { func: (proxies) => {
return proxies.map((proxy) => { return proxies.map((proxy) => {
for (const { expr, now } of regex) { for (const {expr, now} of regex) {
proxy.name = proxy.name.replace(new RegExp(expr, "g"), now).trim(); proxy.name = proxy.name.replace(new RegExp(expr, "g"), now).trim();
} }
return proxy; return proxy;
@ -1882,7 +1873,7 @@ function ScriptOperator(script) {
/**************************** Filters ***************************************/ /**************************** Filters ***************************************/
// filter by keywords // filter by keywords
function KeywordFilter({ keywords = [], keep = true }) { function KeywordFilter({keywords = [], keep = true}) {
return { return {
name: "Keyword Filter", name: "Keyword Filter",
func: (proxies) => { func: (proxies) => {
@ -1937,7 +1928,7 @@ function RegionFilter(regions) {
} }
// filter by regex // filter by regex
function RegexFilter({ regex = [], keep = true }) { function RegexFilter({regex = [], keep = true}) {
return { return {
name: "Regex Filter", name: "Regex Filter",
func: (proxies) => { func: (proxies) => {
@ -2184,7 +2175,7 @@ function removeFlag(str) {
} }
// objClone an object // objClone an object
function objobjClone(obj) { function objClone(obj) {
return JSON.parse(JSON.stringify(obj)); return JSON.parse(JSON.stringify(obj));
} }
@ -2271,20 +2262,22 @@ function ENV() {
return {isQX, isLoon, isSurge, isNode, isJSBox, isRequest}; return {isQX, isLoon, isSurge, isNode, isJSBox, isRequest};
} }
function HTTP(baseURL, defaultOptions = {}) { function HTTP(defaultOptions = {}) {
const { isQX, isLoon, isSurge } = ENV(); const {isQX, isLoon, isSurge} = ENV();
const methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"]; const methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"];
function send(method, options) { function send(method, options) {
options = typeof options === "string" ? { url: options } : options; options = options.hasOwnProperty("url") ? options : {url: options};
options.url = baseURL ? baseURL + options.url : options.url; options.url = defaultOptions.baseURL ? defaultOptions.baseURL + options.url : options.url;
options = { ...defaultOptions, ...options }; options = {...defaultOptions, ...options};
const timeout = options.timeout; const timeout = options.timeout;
const events = { const events = {
...{ ...{
onRequest: () => {}, onRequest: () => {
},
onResponse: (resp) => resp, onResponse: (resp) => resp,
onTimeout: () => {}, onTimeout: () => {
},
}, },
...options.events, ...options.events,
}; };
@ -2293,7 +2286,7 @@ function HTTP(baseURL, defaultOptions = {}) {
let worker; let worker;
if (isQX) { if (isQX) {
worker = $task.fetch({ method, ...options }); worker = $task.fetch({method, ...options});
} else { } else {
worker = new Promise((resolve, reject) => { worker = new Promise((resolve, reject) => {
const request = isSurge || isLoon ? $httpClient : require("request"); const request = isSurge || isLoon ? $httpClient : require("request");
@ -2339,7 +2332,7 @@ function HTTP(baseURL, defaultOptions = {}) {
} }
function API(name = "untitled", debug = false) { function API(name = "untitled", debug = false) {
const { isQX, isLoon, isSurge, isNode, isJSBox } = ENV(); const {isQX, isLoon, isSurge, isNode, isJSBox} = ENV();
return new (class { return new (class {
constructor(name, debug) { constructor(name, debug) {
this.name = name; this.name = name;
@ -2388,7 +2381,7 @@ function API(name = "untitled", debug = false) {
this.node.fs.writeFileSync( this.node.fs.writeFileSync(
fpath, fpath,
JSON.stringify({}), JSON.stringify({}),
{ flag: "wx" }, {flag: "wx"},
(err) => console.log(err) (err) => console.log(err)
); );
} }
@ -2400,7 +2393,7 @@ function API(name = "untitled", debug = false) {
this.node.fs.writeFileSync( this.node.fs.writeFileSync(
fpath, fpath,
JSON.stringify({}), JSON.stringify({}),
{ flag: "wx" }, {flag: "wx"},
(err) => console.log(err) (err) => console.log(err)
); );
this.cache = {}; this.cache = {};
@ -2421,13 +2414,13 @@ function API(name = "untitled", debug = false) {
this.node.fs.writeFileSync( this.node.fs.writeFileSync(
`${this.name}.json`, `${this.name}.json`,
data, data,
{ flag: "w" }, {flag: "w"},
(err) => console.log(err) (err) => console.log(err)
); );
this.node.fs.writeFileSync( this.node.fs.writeFileSync(
"root.json", "root.json",
JSON.stringify(this.root), JSON.stringify(this.root),
{ flag: "w" }, {flag: "w"},
(err) => console.log(err) (err) => console.log(err)
); );
} }
@ -2532,7 +2525,7 @@ function API(name = "untitled", debug = false) {
/*********************************** Mini Express *************************************/ /*********************************** Mini Express *************************************/
function express(port = 3000) { function express(port = 3000) {
const { isNode } = ENV(); const {isNode} = ENV();
const DEFAULT_HEADERS = { const DEFAULT_HEADERS = {
"Content-Type": "text/plain;charset=UTF-8", "Content-Type": "text/plain;charset=UTF-8",
"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Origin": "*",
@ -2546,9 +2539,9 @@ function express(port = 3000) {
const express_ = require("express"); const express_ = require("express");
const bodyParser = require("body-parser"); const bodyParser = require("body-parser");
const app = express_(); const app = express_();
app.use(bodyParser.json({ verify: rawBodySaver })); app.use(bodyParser.json({verify: rawBodySaver}));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true })); app.use(bodyParser.urlencoded({verify: rawBodySaver, extended: true}));
app.use(bodyParser.raw({ verify: rawBodySaver, type: "*/*" })); app.use(bodyParser.raw({verify: rawBodySaver, type: "*/*"}));
app.use((req, res, next) => { app.use((req, res, next) => {
res.set(DEFAULT_HEADERS); res.set(DEFAULT_HEADERS);
next(); next();
@ -2580,19 +2573,21 @@ function express(port = 3000) {
// dispatch url to route // dispatch url to route
const dispatch = (request, start = 0) => { const dispatch = (request, start = 0) => {
let { method, url, headers, body } = request; let {method, url, headers, body} = request;
console.log("DISPATCHING: " + method + ": " + url);
if (/json/i.test(headers["Content-Type"])) { if (/json/i.test(headers["Content-Type"])) {
body = JSON.parse(body); body = JSON.parse(body);
} }
method = method.toUpperCase(); method = method.toUpperCase();
const { path, query } = extractURL(url); const {path, query} = extractURL(url);
let handler = null; let handler = null;
let i; let i;
for (i = start; i < handlers.length; i++) { for (i = start; i < handlers.length; i++) {
if (handlers[i].method === "ALL" || method === handlers[i].method) { if (handlers[i].method === "ALL" || method === handlers[i].method) {
const { pattern } = handlers[i]; const {pattern} = handlers[i];
if (patternMatched(pattern, path)) { if (patternMatched(pattern, path)) {
handler = handlers[i]; handler = handlers[i];
break; break;
@ -2614,9 +2609,6 @@ function express(port = 3000) {
body, body,
}; };
const res = Response(); const res = Response();
if (typeof handler.callback === "undefined") {
$.notify("FUCK");
}
handler.callback(req, res, next).catch((err) => { handler.callback(req, res, next).catch((err) => {
res.status(500).json({ res.status(500).json({
status: "failed", status: "failed",
@ -2639,7 +2631,7 @@ function express(port = 3000) {
METHODS_NAMES.forEach((method) => { METHODS_NAMES.forEach((method) => {
app[method.toLowerCase()] = (pattern, callback) => { app[method.toLowerCase()] = (pattern, callback) => {
// add handler // add handler
handlers.push({ method, pattern, callback }); handlers.push({method, pattern, callback});
}; };
}); });
@ -2649,7 +2641,7 @@ function express(port = 3000) {
METHODS_NAMES.forEach((method) => { METHODS_NAMES.forEach((method) => {
chainApp[method.toLowerCase()] = (callback) => { chainApp[method.toLowerCase()] = (callback) => {
// add handler // add handler
handlers.push({ method, pattern, callback }); handlers.push({method, pattern, callback});
return chainApp; return chainApp;
}; };
}); });
@ -2658,6 +2650,7 @@ function express(port = 3000) {
// start service // start service
app.start = () => { app.start = () => {
console.log(`STARTING TO ROUTE: ${JSON.stringify($request)}`);
dispatch($request); dispatch($request);
}; };
@ -2674,7 +2667,7 @@ function express(port = 3000) {
function Response() { function Response() {
let statusCode = 200; let statusCode = 200;
const { isQX, isLoon, isSurge } = ENV(); const {isQX, isLoon, isSurge} = ENV();
const headers = DEFAULT_HEADERS; const headers = DEFAULT_HEADERS;
const STATUS_CODE_MAP = { const STATUS_CODE_MAP = {
200: "HTTP/1.1 200 OK", 200: "HTTP/1.1 200 OK",

View File

@ -36,7 +36,7 @@ import {axios} from "@/utils";
export default { export default {
name: "ProxyList", name: "ProxyList",
props: ['url'], props: ['url', 'sub'],
data: function (){ data: function (){
return { return {
proxies: [] proxies: []
@ -44,7 +44,7 @@ export default {
}, },
methods: { methods: {
refresh() { refresh() {
axios.post(`/refresh`, {url: this.url}).then(() => { axios.post(`/refresh`, {url: this.sub}).then(() => {
this.fetch(); this.fetch();
}) })
}, },

View File

@ -1,2 +1,3 @@
const DEBUG = process.env.NODE_ENV === "development"; // const DEBUG = process.env.NODE_ENV === "development";
const DEBUG = false;
export const BACKEND_BASE = DEBUG ? `http://192.168.1.134:3000` : `https://sub.store`; export const BACKEND_BASE = DEBUG ? `http://192.168.1.134:3000` : `https://sub.store`;

View File

@ -148,7 +148,7 @@
</v-toolbar> </v-toolbar>
</v-card-title> </v-card-title>
<v-card-text class="pl-0 pr-0"> <v-card-text class="pl-0 pr-0">
<proxy-list :url="url" ref="proxyList" :key="url"></proxy-list> <proxy-list :url="url" :sub="sub" ref="proxyList" :key="url"></proxy-list>
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-dialog> </v-dialog>
@ -166,6 +166,7 @@ export default {
opened: false, opened: false,
showProxyList: false, showProxyList: false,
url: "", url: "",
sub: [],
editMenu: [ editMenu: [
{ {
title: "复制", title: "复制",
@ -227,7 +228,8 @@ export default {
}, },
preview(item, type = 'sub') { preview(item, type = 'sub') {
if (type === 'sub') { if (type === 'sub') {
this.url = `${BACKEND_BASE}/download/${item.name}` this.url = `${BACKEND_BASE}/download/${item.name}`;
this.sub = [item.url];
} else { } else {
this.url = `${BACKEND_BASE}/download/collection/${item.name}` this.url = `${BACKEND_BASE}/download/collection/${item.name}`
} }