diff --git a/Basis/Exception.py b/Basis/Exception.py index 685b394..8192bea 100644 --- a/Basis/Exception.py +++ b/Basis/Exception.py @@ -4,3 +4,8 @@ class buildException(Exception): # for build error def __init__(self, reason): self.reason = reason + + +class filterException(Exception): # for filter error + def __init__(self, reason): + self.reason = reason diff --git a/Basis/Filter.py b/Basis/Filter.py index fdc81a5..341c851 100644 --- a/Basis/Filter.py +++ b/Basis/Filter.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import copy +from Basis.Exception import filterException filterObject = { 'optional': { @@ -67,7 +68,7 @@ for field in filterObject: def Filter(raw: dict, rules: dict) -> dict: if type(raw) != dict: - raise RuntimeError('Invalid input for filter') + raise filterException('Invalid input for filter') data = {} raw = copy.deepcopy(raw) rules = copy.deepcopy(rules) @@ -75,19 +76,19 @@ def Filter(raw: dict, rules: dict) -> dict: # pretreatment process (raw --[copy / default value]--> data) if key not in raw: # key not exist if not rule['optional']: # force require key not exist - raise RuntimeError('Missing `%s` field' % key) + raise filterException('Missing `%s` field' % key) data[key] = rule['default'] # set default value else: # key exist data[key] = raw[key] # format process (data --[format]--> data) if data[key] is None: # key content is None if not rule['allowNone']: # key is not allow None - raise RuntimeError('Field `%s` shouldn\'t be None' % key) + raise filterException('Field `%s` shouldn\'t be None' % key) continue # skip following process try: data[key] = rule['format'](data[key]) # run format except: - raise RuntimeError(rule['errMsg']) # format error + raise filterException(rule['errMsg']) # format error # filter process (data --[type check (& filter check)]--> pass / non-pass) if type(rule['type']) == type: # str / int / bool / ... rule['type'] = [rule['type']] # str -> [str] / int -> [int] / ... @@ -95,35 +96,38 @@ def Filter(raw: dict, rules: dict) -> dict: if data[key] == any and any in rule['type']: # special case -> skip type filter pass elif type(data[key]) not in rule['type']: # type not in allow list - raise RuntimeError('Invalid `%s` field' % key) + raise filterException('Invalid `%s` field' % key) elif type(rule['type']) == dict: # check subObject if type(data[key]) != dict: - raise RuntimeError('Invalid sub object in `%s`' % key) # subObject content should be dict + raise filterException('Invalid sub object in `%s`' % key) # subObject content should be dict if not rule['multiSub']: # single subObject subRules = rule['type'] else: # multi subObject if rule['indexKey'] not in data[key]: # confirm index key exist - raise RuntimeError('Index key `%s` not found in `%s`' % (rule['indexKey'], key)) + raise filterException('Index key `%s` not found in `%s`' % (rule['indexKey'], key)) subType = data[key][rule['indexKey']].lower() if subType not in rule['type']: # confirm subObject rule exist - raise RuntimeError('Unknown index `%s` in key `%s`' % (subType, key)) + raise filterException('Unknown index `%s` in key `%s`' % (subType, key)) subRules = rule['type'][subType] try: data[key] = Filter(data[key], subRules) - except RuntimeError as exp: - raise RuntimeError('%s (in `%s`)' % (exp, key)) # add located info + except filterException as exp: + raise filterException('%s (in `%s`)' % (exp, key)) # add located info continue elif rule['type'] != any: # type == any -> skip type filter - raise RuntimeError('Unknown `type` in rules') + raise filterException('Unknown `type` in rules') if not rule['filter'](data[key]): # run filter - raise RuntimeError(rule['errMsg']) + raise filterException(rule['errMsg']) return data def rulesFilter(rules: dict) -> dict: result = {} for key, rule in rules.items(): # filter by basic rules - result[key] = Filter(rule, filterObject) + try: + result[key] = Filter(rule, filterObject) + except filterException as exp: + raise filterException('%s (`%s` in rules)' % (exp, key)) # rules error return result diff --git a/Builder/__init__.py b/Builder/__init__.py index 5bbe0dc..63aea63 100644 --- a/Builder/__init__.py +++ b/Builder/__init__.py @@ -3,12 +3,13 @@ import os import copy +from Filter import Filter from Basis.Logger import logging from Basis.Process import Process from Basis.Functions import v6AddBracket -from Basis.Exception import buildException from Basis.Constant import WorkDir, PathEnv from Basis.Functions import genFlag, getAvailablePort +from Basis.Exception import buildException, filterException from Builder import Brook from Builder import VMess @@ -73,6 +74,7 @@ class Builder(object): logging.error('[%s] Builder receive unknown proxy type %s' % (self.id, proxyType)) raise buildException('Unknown proxy type') self.proxyType = proxyType # proxy type -> ss / ssr / vmess ... + self.proxyInfo = Filter(proxyType, proxyInfo) # filter input proxy info self.proxyInfo = copy.copy(proxyInfo) # connection info self.socksAddr = bindAddr self.socksPort = getAvailablePort() # random port for socks5 exposed diff --git a/Filter/__init__.py b/Filter/__init__.py index 4b571b5..25d071e 100644 --- a/Filter/__init__.py +++ b/Filter/__init__.py @@ -9,6 +9,7 @@ from Filter.Shadowsocks import ssFilter from Filter.ShadowsocksR import ssrFilter from Filter.TrojanGo import trojanGoFilter from Filter.Hysteria import hysteriaFilter +from Basis.Exception import filterException filterEntry = { 'ss': ssFilter, @@ -23,5 +24,10 @@ filterEntry = { def Filter(proxyType: str, proxyInfo: dict) -> dict: if proxyType not in filterEntry: - raise RuntimeError('Unknown proxy type') - return filterEntry[proxyType](proxyInfo) + raise filterException('Unknown proxy type') + try: + return filterEntry[proxyType](proxyInfo) + except filterException as exp: + raise filterException(exp) + except: + raise filterException('Unknown filter error')