From 0c6fe80b99477fbb7b63d30b16088465fbbadbba Mon Sep 17 00:00:00 2001 From: dnomd343 Date: Fri, 5 Aug 2022 12:25:33 +0800 Subject: [PATCH] feat: filter design --- Basis/Functions.py | 20 +++++++++++++++ Filter/Plugin.py | 5 ++++ Filter/Shadowsocks.py | 56 +++++++++++++++++++++++++++++++++++++++++ Filter/__init__.py | 58 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 Filter/Plugin.py create mode 100644 Filter/Shadowsocks.py create mode 100644 Filter/__init__.py diff --git a/Basis/Functions.py b/Basis/Functions.py index ffb0565..544de97 100644 --- a/Basis/Functions.py +++ b/Basis/Functions.py @@ -86,3 +86,23 @@ def networkStatus() -> list: # get all network connections }) logging.debug('Network status -> found %i connections' % len(result)) return result + + +def toInt(raw) -> int: + pass + + +def toStr(raw) -> str: + pass + + +def toBool(raw) -> bool: + pass + + +def isHost(raw) -> bool: + pass + + +def isPort(raw) -> bool: + pass diff --git a/Filter/Plugin.py b/Filter/Plugin.py new file mode 100644 index 0000000..2b98da0 --- /dev/null +++ b/Filter/Plugin.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +def pluginFormat(pluginName: str) -> str: + return pluginName diff --git a/Filter/Shadowsocks.py b/Filter/Shadowsocks.py new file mode 100644 index 0000000..9702174 --- /dev/null +++ b/Filter/Shadowsocks.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from Filter.Plugin import pluginFormat +from Basis.Functions import toInt, toStr +from Basis.Functions import isHost, isPort +from Basis.Constant import ssMethods, pluginClients + +pluginObject = { + 'type': { + 'type': str, + 'format': lambda s: pluginFormat(toStr(s).strip().lower()), + 'filter': lambda s: s in pluginClients, + 'errMsg': 'Unknown SIP003 plugin' + }, + 'param': { + 'optional': False, + 'default': '', + 'type': str, + 'format': toStr, + 'errMsg': 'Invalid SIP003 param' + } +} + +ssObject = { + 'server': { + 'type': str, + 'format': toStr, + 'filter': isHost, + 'errMsg': 'Invalid server address' + }, + 'port': { + 'type': int, + 'format': toInt, + 'filter': isPort, + 'errMsg': 'Invalid port number' + }, + 'method': { + 'type': str, + 'format': lambda s: toStr(s).strip().lower().replace('_', '-'), + 'filter': lambda s: s in ssMethods, + 'errMsg': 'Unknown Shadowsocks method' + }, + 'passwd': { + 'type': str, + 'format': toStr, + 'errMsg': 'Invalid password content' + }, + 'plugin': { + 'optional': False, + 'default': None, + 'allowNone': True, + 'type': pluginObject, + 'errMsg': 'Invalid pluginObject' + } +} diff --git a/Filter/__init__.py b/Filter/__init__.py new file mode 100644 index 0000000..50635e4 --- /dev/null +++ b/Filter/__init__.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +xxObject = { # a dict that describe multi-field + 'field_1': { + 'optional': ..., # field force require or not + 'default': ..., # default value when field is not exist (optional == True) + 'allowNone': ..., # whether the value can be None (override the format and filter process) + 'type': ..., # type of field content (in filter process) (python type / dict) + 'multiSub': ..., # whether there are multi subObject (type is dict) + 'indexKey': ..., # index key of subObject (type is dict and multiSub == True) + 'format': ..., # format function (before filter process) (invalid content -> throw error) + 'filter': ..., # filter function -> bool (throw error when return False) + 'errMsg': ..., # raise message if there is something error + }, + 'field_2': { + ... + }, + ... +} + + +default value + + optional: False + + default: None + + allowNone: False + + format: lambda -> return same thing + + type: force require + + multiSub: False + + indexKey: 'type' + + filter: lambda -> return True + + errMsg: 'filter error' + + +pre process + => field not exist + => optional == False -> throw errMsg + => optional == True -> set as default value -> continue + => field exist + => filed is None + => allowNone is False -> throw errMsg + => allowNone is True -> break + => field is not None -> continue + +format process -> set as field value (maybe throw error -> catch and throw errMsg) + +filter process + => type is `python type` -> compare with field type -> filter function check + => type is dict + => multiSub == False -> recursive check + => multiSub == True + => field content is not dict or not include indexKey -> throw error + => others + => indexKey's content not in type (dict) -> throw error + => others -> recursive check + +"""