Browse Source

update: new formatting rules

master
Dnomd343 3 years ago
parent
commit
21e1129713
  1. 4
      ProxyBuilder/Shadowsocks.py
  2. 8
      ProxyBuilder/builder.py
  3. 8
      ProxyDecoder/Shadowsocks.py
  4. 79
      ProxyFilter/Shadowsocks.py
  5. 81
      ProxyFilter/ShadowsocksR.py
  6. 13
      ProxyFilter/baseFunc.py
  7. 8
      ProxyFilter/filter.py
  8. 2
      Web.py
  9. 31
      docs/ProxyObject.md

4
ProxyBuilder/Shadowsocks.py

@ -206,8 +206,8 @@ def __ssFormatCheck(proxyInfo: dict) -> bool: # Shadowsocks参数检查
return False return False
if 'plugin' not in proxyInfo: if 'plugin' not in proxyInfo:
return False return False
plugin = proxyInfo['plugin'] plugin = proxyInfo['plugin'] # plugin -> dict / None
if isinstance(plugin, dict): # plugin -> dict / None if isinstance(plugin, dict):
if 'type' not in plugin or not isinstance(plugin['type'], str): # plugin.type -> str if 'type' not in plugin or not isinstance(plugin['type'], str): # plugin.type -> str
return False return False
if 'param' not in plugin or not isinstance(plugin['param'], str): # plugin.param -> str if 'param' not in plugin or not isinstance(plugin['param'], str): # plugin.param -> str

8
ProxyBuilder/builder.py

@ -54,7 +54,7 @@ def __checkPortAvailable(port: int) -> bool: # 检测端口可用性
ipv6_udp.close() ipv6_udp.close()
except: pass except: pass
def __genTaskFlag(length: int = 16) -> str: # 生成任务代号 def __genTaskFlag(length: int = 16) -> str: # 生成任务标志
flag = '' flag = ''
for i in range(0, length): for i in range(0, length):
tmp = random.randint(0, 15) tmp = random.randint(0, 15)
@ -64,14 +64,14 @@ def __genTaskFlag(length: int = 16) -> str: # 生成任务代号
flag += str(tmp) # 0 ~ 9 flag += str(tmp) # 0 ~ 9
return flag return flag
def __getAvailablePort(rangeStart: int, rangeEnd: int) -> int or None: # 获取一个空闲端口 def __getAvailablePort(rangeStart: int = 41952, rangeEnd: int = 65535) -> int or None: # 获取一个空闲端口
if rangeStart > rangeEnd or rangeStart < 0 or rangeEnd > 65535: if rangeStart > rangeEnd or rangeStart < 1 or rangeEnd > 65535:
return None return None
while True: while True:
port = random.randint(rangeStart, rangeEnd) # 随机选取 port = random.randint(rangeStart, rangeEnd) # 随机选取
if __checkPortAvailable(port): if __checkPortAvailable(port):
return port return port
time.sleep(0.1) # 100ms time.sleep(0.1) # wait for 100ms
def build(proxyInfo: dict, configDir: str, def build(proxyInfo: dict, configDir: str,
portRangeStart: int = 1024, portRangeEnd: int = 65535) -> tuple[bool or None, str or dict]: portRangeStart: int = 1024, portRangeEnd: int = 65535) -> tuple[bool or None, str or dict]:

8
ProxyDecoder/Shadowsocks.py

@ -111,16 +111,20 @@ def __sip002Decode(url: str) -> dict or None:
plugin = baseFunc.urlDecode(field.group(2)) # plugin参数 plugin = baseFunc.urlDecode(field.group(2)) # plugin参数
break break
if plugin.find(';') == -1: # plugin=... (无参数) if plugin.find(';') == -1: # plugin=... (无参数)
info['plugin'] = { pluginField = {
'type': plugin, 'type': plugin,
'param': '' 'param': ''
} }
else: # plugin=...;... (带参数) else: # plugin=...;... (带参数)
plugin = re.search(r'^([\S]*?);([\S]*)$', plugin) # 插件名;插件参数 plugin = re.search(r'^([\S]*?);([\S]*)$', plugin) # 插件名;插件参数
info['plugin'] = { pluginField = {
'type': plugin.group(1), 'type': plugin.group(1),
'param': plugin.group(2) 'param': plugin.group(2)
} }
if pluginField['type'] == '': # 无插件情况
info['plugin'] = None
else:
info['plugin'] = pluginField
return info return info
except: except:
return None return None

79
ProxyFilter/Shadowsocks.py

@ -76,8 +76,6 @@ def __ssFill(raw: dict) -> dict: # 补全可选值
if 'plugin' not in raw: if 'plugin' not in raw:
raw['plugin'] = None raw['plugin'] = None
if raw['plugin'] is not None: if raw['plugin'] is not None:
if 'type' not in raw['plugin']:
raw['plugin']['type'] = ''
if 'param' not in raw['plugin']: if 'param' not in raw['plugin']:
raw['plugin']['param'] = '' raw['plugin']['param'] = ''
except: except:
@ -89,13 +87,65 @@ def __ssFormat(raw: dict) -> dict: # 容错性格式化
raw['server'] = raw['server'].strip() raw['server'] = raw['server'].strip()
raw['port'] = int(raw['port']) raw['port'] = int(raw['port'])
raw['method'] = raw['method'].replace('_', '-').lower().strip() raw['method'] = raw['method'].replace('_', '-').lower().strip()
if isinstance(raw['plugin'], str):
raw['plugin'] = raw['plugin'].strip()
if raw['plugin'] == '':
raw['plugin'] = None
else:
raw['plugin'] = {
'type': raw['plugin'],
'param': ''
}
if raw['plugin'] is not None: if raw['plugin'] is not None:
if isinstance(raw['plugin']['type'], str):
raw['plugin']['type'] = raw['plugin']['type'].strip()
if raw['plugin']['type'] in [None, '']:
raw['plugin'] = None
else:
raw['plugin']['type'] = sip003.pluginFormat(raw['plugin']['type']) raw['plugin']['type'] = sip003.pluginFormat(raw['plugin']['type'])
except: except:
pass pass
return raw return raw
def ssFilter(raw: dict) -> tuple[bool, str or dict]: def __ssParamCheck(raw: dict) -> tuple[bool, str or None]: # 参数检查
try:
if 'server' not in raw:
return False, 'Missing `server` option'
if 'port' not in raw:
return False, 'Missing `port` option'
if 'method' not in raw:
return False, 'Missing `method` option'
if 'passwd' not in raw:
return False, 'Missing `passwd` option'
if 'plugin' not in raw:
return False, 'Missing `plugin` option'
if raw['plugin'] is not None:
if 'type' not in raw['plugin']:
return False, 'Missing `plugin.type` option'
if 'param' not in raw['plugin']:
return False, 'Missing `plugin.param` option'
if not isinstance(raw['server'], str):
return False, 'Illegal `server` option'
if not isinstance(raw['port'], int):
return False, 'Illegal `int` option'
if not isinstance(raw['method'], str):
return False, 'Illegal `method` option'
if not isinstance(raw['passwd'], str):
return False, 'Illegal `passwd` option'
if (raw['plugin'] is not None) and (not isinstance(raw['plugin'], dict)):
return False, 'Illegal `plugin` option'
if raw['plugin'] is not None:
if not isinstance(raw['plugin']['type'], str):
return False, 'Illegal `plugin.type` option'
if not isinstance(raw['plugin']['param'], str):
return False, 'Illegal `plugin.param` option'
except:
return False, 'Unknown error'
return True, None
def ssFilter(rawInfo: dict, isExtra: bool) -> tuple[bool, str or dict]:
""" """
Shadowsocks节点合法性检查 Shadowsocks节点合法性检查
@ -109,17 +159,22 @@ def ssFilter(raw: dict) -> tuple[bool, str or dict]:
} }
""" """
try: try:
if 'server' not in raw: # 必选值检查 raw = rawInfo
return False, 'Missing `server` option'
if 'port' not in raw:
return False, 'Missing `port` option'
if 'method' not in raw:
return False, 'Missing `method` option'
if 'passwd' not in raw:
return False, 'Missing `passwd` option'
raw = __ssFormat(__ssFill(raw)) # 预处理 raw = __ssFormat(__ssFill(raw)) # 预处理
status, reason = __ssParamCheck(raw) # 参数检查
if not status: # 参数有误
return False, reason
result = {'type': 'ss'} result = {'type': 'ss'}
if isExtra: # 携带额外参数
if 'remark' not in raw: # 补全默认值
raw['remark'] = ''
if raw['remark'] is None: # 容错格式化
raw['remark'] = ''
if not isinstance(raw['remark'], str): # 参数检查
return False, 'Illegal `remark` option'
result['remark'] = raw['remark']
if baseFunc.isHost(raw['server']): if baseFunc.isHost(raw['server']):
result['server'] = raw['server'] # server result['server'] = raw['server'] # server
else: else:
@ -134,7 +189,7 @@ def ssFilter(raw: dict) -> tuple[bool, str or dict]:
return False, 'Unknown Shadowsocks method' return False, 'Unknown Shadowsocks method'
result['passwd'] = raw['passwd'] # passwd result['passwd'] = raw['passwd'] # passwd
if raw['plugin'] is None or raw['plugin']['type'] in [None, '']: if raw['plugin'] is None:
plugin = None plugin = None
else: else:
if raw['plugin']['type'] in pluginList: if raw['plugin']['type'] in pluginList:

81
ProxyFilter/ShadowsocksR.py

@ -92,14 +92,60 @@ def __ssrFormat(raw: dict) -> dict: # 容错性格式化
raw['server'] = raw['server'].strip() raw['server'] = raw['server'].strip()
raw['port'] = int(raw['port']) raw['port'] = int(raw['port'])
raw['method'] = raw['method'].replace('_', '-').lower().strip() raw['method'] = raw['method'].replace('_', '-').lower().strip()
if raw['protocol'] is None:
raw['protocol'] = ''
if raw['protocolParam'] is None:
raw['protocolParam'] = ''
if raw['obfs'] is None:
raw['obfs'] = ''
if raw['obfsParam'] is None:
raw['obfsParam'] = ''
raw['protocol'] = raw['protocol'].replace('-', '_').lower().strip() raw['protocol'] = raw['protocol'].replace('-', '_').lower().strip()
raw['obfs'] = raw['obfs'].replace('-', '_').lower().strip() raw['obfs'] = raw['obfs'].replace('-', '_').lower().strip()
except: except:
pass pass
return raw return raw
def __ssrParamCheck(raw: dict) -> tuple[bool, str or None]: # 参数检查
try:
if 'server' not in raw:
return False, 'Missing `server` option'
if 'port' not in raw:
return False, 'Missing `port` option'
if 'method' not in raw:
return False, 'Missing `method` option'
if 'passwd' not in raw:
return False, 'Missing `passwd` option'
if 'protocol' not in raw:
return False, 'Missing `protocol` option'
if 'protocolParam' not in raw:
return False, 'Missing `protocolParam` option'
if 'obfs' not in raw:
return False, 'Missing `obfs` option'
if 'obfsParam' not in raw:
return False, 'Missing `obfsParam` option'
def ssrFilter(raw: dict) -> tuple[bool, str or dict]: if not isinstance(raw['server'], str):
return False, 'Illegal `server` option'
if not isinstance(raw['port'], int):
return False, 'Illegal `int` option'
if not isinstance(raw['method'], str):
return False, 'Illegal `method` option'
if not isinstance(raw['passwd'], str):
return False, 'Illegal `passwd` option'
if not isinstance(raw['protocol'], str):
return False, 'Illegal `protocol` option'
if not isinstance(raw['protocolParam'], str):
return False, 'Illegal `protocolParam` option'
if not isinstance(raw['obfs'], str):
return False, 'Illegal `obfs` option'
if not isinstance(raw['obfsParam'], str):
return False, 'Illegal `obfsParam` option'
except:
return False, 'Unknown error'
return True, None
def ssrFilter(rawInfo: dict, isExtra: bool) -> tuple[bool, str or dict]:
""" """
ShadowsocksR节点合法性检查 ShadowsocksR节点合法性检查
@ -113,18 +159,29 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
} }
""" """
try: try:
raw = rawInfo
if 'server' not in raw: # 必选值检查
return False, 'Missing `server` option'
if 'port' not in raw:
return False, 'Missing `port` option'
if 'method' not in raw:
return False, 'Missing `method` option'
if 'passwd' not in raw:
return False, 'Missing `password` option'
raw = __ssrFormat(__ssrFill(raw)) # 预处理 raw = __ssrFormat(__ssrFill(raw)) # 预处理
status, reason = __ssrParamCheck(raw) # 参数检查
if not status: # 参数有误
return False, reason
result = {'type': 'ssr'} result = {'type': 'ssr'}
if isExtra: # 携带额外参数
if 'remark' not in raw: # 补全默认值
raw['remark'] = ''
if 'group' not in raw:
raw['group'] = ''
if raw['remark'] is None: # 容错格式化
raw['remark'] = ''
if raw['group'] is None:
raw['group'] = ''
if not isinstance(raw['remark'], str): # 参数检查
return False, 'Illegal `remark` option'
if not isinstance(raw['group'], str):
return False, 'Illegal `group` option'
result['remark'] = raw['remark']
result['group'] = raw['group']
if baseFunc.isHost(raw['server']): if baseFunc.isHost(raw['server']):
result['server'] = raw['server'] # server result['server'] = raw['server'] # server
else: else:
@ -139,7 +196,7 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
return False, 'Unknown ShadowsocksR method' return False, 'Unknown ShadowsocksR method'
result['passwd'] = raw['passwd'] # passwd result['passwd'] = raw['passwd'] # passwd
if raw['protocol'] in [None, '', 'origin']: # 默认协议 if raw['protocol'] in ['', 'origin']: # 默认协议
result['protocol'] = 'origin' result['protocol'] = 'origin'
result['protocolParam'] = '' result['protocolParam'] = ''
else: else:
@ -149,7 +206,7 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
else: else:
return False, 'Unknown ShadowsocksR protocol' return False, 'Unknown ShadowsocksR protocol'
if raw['obfs'] in [None, '', 'plain']: # 默认混淆 if raw['obfs'] in ['', 'plain']: # 默认混淆
result['obfs'] = 'plain' result['obfs'] = 'plain'
result['obfsParam'] = '' result['obfsParam'] = ''
else: else:

13
ProxyFilter/baseFunc.py

@ -18,10 +18,15 @@ def isHost(host: str) -> bool:
IPy.IP(host) IPy.IP(host)
if host.find('/') != -1: # filter CIDR if host.find('/') != -1: # filter CIDR
return False return False
return True return True # IP地址合法
except: # not IP address except:
pass pass
return re.search(r'^(?=^.{3,255}$)[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62}(\.[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62})+$', host) is not None try:
return re.search( # 域名匹配
r'^(?=^.{3,255}$)[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62}(\.[a-zA-Z0-9_][a-zA-Z0-9_-]{0,62})+$', host
) is not None
except: # 异常错误
return False
def isPort(port: int) -> bool: def isPort(port: int) -> bool:
""" """
@ -34,7 +39,7 @@ def isPort(port: int) -> bool:
不合法: return False 不合法: return False
""" """
try: try:
if 1 <= port <= 65535: if 1 <= port <= 65535: # 1 ~ 65535
return True return True
except: # illegal except: # illegal
pass pass

8
ProxyFilter/filter.py

@ -4,7 +4,7 @@
from ProxyFilter import Shadowsocks from ProxyFilter import Shadowsocks
from ProxyFilter import ShadowsocksR from ProxyFilter import ShadowsocksR
def filte(raw: dict) -> tuple[bool, str]: def filte(raw: dict, isExtra: bool = False) -> tuple[bool, str]:
""" """
代理信息过滤并格式化 代理信息过滤并格式化
@ -13,7 +13,7 @@ def filte(raw: dict) -> tuple[bool, str]:
参数有效: 参数有效:
return True, { return True, {
'...': '...', 'type': '...',
'...': '...', '...': '...',
... ...
} }
@ -22,9 +22,9 @@ def filte(raw: dict) -> tuple[bool, str]:
if 'type' not in raw: if 'type' not in raw:
return False, 'Missing `type` option' return False, 'Missing `type` option'
if raw['type'] == 'ss': if raw['type'] == 'ss':
return Shadowsocks.ssFilter(raw) return Shadowsocks.ssFilter(raw, isExtra)
elif raw['type'] == 'ssr': elif raw['type'] == 'ssr':
return ShadowsocksR.ssrFilter(raw) return ShadowsocksR.ssrFilter(raw, isExtra)
else: else:
return False, 'Unknown proxy type' return False, 'Unknown proxy type'
except: except:

2
Web.py

@ -71,7 +71,7 @@ def addCheckTask(checkList: dict, proxyList: dict, priority: str, userId: str) -
proxyList[i] = Decoder.decode(proxyList[i]) # 解码分享链接 proxyList[i] = Decoder.decode(proxyList[i]) # 解码分享链接
if proxyList[i] is None: if proxyList[i] is None:
return genError('could not decode index ' + str(i)) return genError('could not decode index ' + str(i))
status, proxyList[i] = Filter.filte(proxyList[i]) # 节点信息检查 status, proxyList[i] = Filter.filte(proxyList[i], isExtra = True) # 节点信息检查
if not status: # 节点不合法 if not status: # 节点不合法
return genError('index ' + str(i) + ': ' + proxyList[i]) return genError('index ' + str(i) + ': ' + proxyList[i])

31
docs/ProxyObject.md

@ -19,6 +19,16 @@
## Shadowsocks ## Shadowsocks
> **remark**
>
> + 类型:*str*
>
> + 说明:节点备注名称
>
> + 缺省:''
>
> + 可选值:不限
``` ```
{ {
'type': 'ss', 'type': 'ss',
@ -113,6 +123,27 @@
## ShadowsocksR ## ShadowsocksR
> **remark**
>
> + 类型:*str*
>
> + 说明:节点备注名称
>
> + 缺省:''
>
> + 可选值:不限
>
> **group**
>
> + 类型:*str*
>
> + 说明:节点所属群组
>
> + 缺省:''
>
> + 可选值:不限
``` ```
{ {
'type': 'ssr', 'type': 'ssr',

Loading…
Cancel
Save