From bc58419bb1cf306fd82892b7547a488a16315aa3 Mon Sep 17 00:00:00 2001 From: Peng-YM <1048217874pengym@gmail.com> Date: Wed, 6 Jul 2022 15:34:30 +0800 Subject: [PATCH] feat: Added Conditional Filter --- .../src/core/proxy-utils/processors/index.js | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/backend/src/core/proxy-utils/processors/index.js b/backend/src/core/proxy-utils/processors/index.js index f461fed..49978f6 100644 --- a/backend/src/core/proxy-utils/processors/index.js +++ b/backend/src/core/proxy-utils/processors/index.js @@ -4,6 +4,65 @@ import { getFlag } from '@/utils/geo'; import lodash from 'lodash'; import $ from '@/core/app'; +/** +The rule "(name CONTAINS "🇨🇳") AND (port IN [80, 443])" can be expressed as follows: +{ + operator: "AND", + child: [ + { + attr: "name", + proposition: "CONTAINS", + value: "🇨🇳" + }, + { + attr: "port", + proposition: "IN", + value: [80, 443] + } + ] +} +*/ + +function ConditionalFilter({ rule }) { + return { + name: 'Conditional Filter', + func: (proxies) => { + return proxies.map(proxy => isMatch(rule, proxy)); + } + } +} + +function isMatch(rule, proxy) { + // leaf node + if (!rule.operator) { + switch (rule.proposition) { + case "IN": + return rule.value.indexOf(proxy[rule.attr]) !== -1; + case "CONTAINS": + if (typeof proxy[rule.attr] !== "string") return false; + return proxy[rule.attr].indexOf(rule.value) !== -1; + case "EQUALS": + return proxy[rule.attr] === rule.value; + case "EXISTS": + return proxy[rule.attr] !== null || typeof proxy[rule.attr] !== "undefined"; + default: + throw new Error(`Unknown proposition: ${rule.proposition}`); + } + } + + // operator nodes + switch (rule.operator) { + case "AND": + return rule.child.every(child => isMatch(child, proxy)); + case "OR": + return rule.child.some(child => isMatch(child, proxy)); + case "NOT": + return !isMatch(rule.child, proxy); + default: + throw new Error(`Unknown operator: ${rule.operator}`); + } +} + function QuickSettingOperator(args) { return { name: 'Quick Setting Operator', @@ -465,6 +524,7 @@ export default { 'Regex Filter': RegexFilter, 'Type Filter': TypeFilter, 'Script Filter': ScriptFilter, + 'Conditional Filter': ConditionalFilter, 'Quick Setting Operator': QuickSettingOperator, 'Flag Operator': FlagOperator,