Browse Source

update: new formatting rules

master
Dnomd343 2 years ago
parent
commit
21e1129713
  1. 4
      ProxyBuilder/Shadowsocks.py
  2. 8
      ProxyBuilder/builder.py
  3. 8
      ProxyDecoder/Shadowsocks.py
  4. 83
      ProxyFilter/Shadowsocks.py
  5. 83
      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
if 'plugin' not in proxyInfo:
return False
plugin = proxyInfo['plugin']
if isinstance(plugin, dict): # plugin -> dict / None
plugin = proxyInfo['plugin'] # plugin -> dict / None
if isinstance(plugin, dict):
if 'type' not in plugin or not isinstance(plugin['type'], str): # plugin.type -> str
return False
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()
except: pass
def __genTaskFlag(length: int = 16) -> str: # 生成任务代号
def __genTaskFlag(length: int = 16) -> str: # 生成任务标志
flag = ''
for i in range(0, length):
tmp = random.randint(0, 15)
@ -64,14 +64,14 @@ def __genTaskFlag(length: int = 16) -> str: # 生成任务代号
flag += str(tmp) # 0 ~ 9
return flag
def __getAvailablePort(rangeStart: int, rangeEnd: int) -> int or None: # 获取一个空闲端口
if rangeStart > rangeEnd or rangeStart < 0 or rangeEnd > 65535:
def __getAvailablePort(rangeStart: int = 41952, rangeEnd: int = 65535) -> int or None: # 获取一个空闲端口
if rangeStart > rangeEnd or rangeStart < 1 or rangeEnd > 65535:
return None
while True:
port = random.randint(rangeStart, rangeEnd) # 随机选取
if __checkPortAvailable(port):
return port
time.sleep(0.1) # 100ms
time.sleep(0.1) # wait for 100ms
def build(proxyInfo: dict, configDir: str,
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参数
break
if plugin.find(';') == -1: # plugin=... (无参数)
info['plugin'] = {
pluginField = {
'type': plugin,
'param': ''
}
else: # plugin=...;... (带参数)
plugin = re.search(r'^([\S]*?);([\S]*)$', plugin) # 插件名;插件参数
info['plugin'] = {
pluginField = {
'type': plugin.group(1),
'param': plugin.group(2)
}
if pluginField['type'] == '': # 无插件情况
info['plugin'] = None
else:
info['plugin'] = pluginField
return info
except:
return None

83
ProxyFilter/Shadowsocks.py

@ -76,8 +76,6 @@ def __ssFill(raw: dict) -> dict: # 补全可选值
if 'plugin' not in raw:
raw['plugin'] = None
if raw['plugin'] is not None:
if 'type' not in raw['plugin']:
raw['plugin']['type'] = ''
if 'param' not in raw['plugin']:
raw['plugin']['param'] = ''
except:
@ -89,13 +87,65 @@ def __ssFormat(raw: dict) -> dict: # 容错性格式化
raw['server'] = raw['server'].strip()
raw['port'] = int(raw['port'])
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:
raw['plugin']['type'] = sip003.pluginFormat(raw['plugin']['type'])
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'])
except:
pass
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节点合法性检查
@ -109,17 +159,22 @@ def ssFilter(raw: dict) -> tuple[bool, str or dict]:
}
"""
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'
raw = __ssFormat(__ssFill(raw)) # 预处理
raw = rawInfo
raw = __ssFormat(__ssFill(raw)) # 预处理
status, reason = __ssParamCheck(raw) # 参数检查
if not status: # 参数有误
return False, reason
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']):
result['server'] = raw['server'] # server
else:
@ -134,7 +189,7 @@ def ssFilter(raw: dict) -> tuple[bool, str or dict]:
return False, 'Unknown Shadowsocks method'
result['passwd'] = raw['passwd'] # passwd
if raw['plugin'] is None or raw['plugin']['type'] in [None, '']:
if raw['plugin'] is None:
plugin = None
else:
if raw['plugin']['type'] in pluginList:

83
ProxyFilter/ShadowsocksR.py

@ -92,14 +92,60 @@ def __ssrFormat(raw: dict) -> dict: # 容错性格式化
raw['server'] = raw['server'].strip()
raw['port'] = int(raw['port'])
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['obfs'] = raw['obfs'].replace('-', '_').lower().strip()
except:
pass
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节点合法性检查
@ -113,18 +159,29 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
}
"""
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 `password` option'
raw = __ssrFormat(__ssrFill(raw)) # 预处理
raw = rawInfo
raw = __ssrFormat(__ssrFill(raw)) # 预处理
status, reason = __ssrParamCheck(raw) # 参数检查
if not status: # 参数有误
return False, reason
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']):
result['server'] = raw['server'] # server
else:
@ -139,7 +196,7 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
return False, 'Unknown ShadowsocksR method'
result['passwd'] = raw['passwd'] # passwd
if raw['protocol'] in [None, '', 'origin']: # 默认协议
if raw['protocol'] in ['', 'origin']: # 默认协议
result['protocol'] = 'origin'
result['protocolParam'] = ''
else:
@ -149,7 +206,7 @@ def ssrFilter(raw: dict) -> tuple[bool, str or dict]:
else:
return False, 'Unknown ShadowsocksR protocol'
if raw['obfs'] in [None, '', 'plain']: # 默认混淆
if raw['obfs'] in ['', 'plain']: # 默认混淆
result['obfs'] = 'plain'
result['obfsParam'] = ''
else:

13
ProxyFilter/baseFunc.py

@ -18,10 +18,15 @@ def isHost(host: str) -> bool:
IPy.IP(host)
if host.find('/') != -1: # filter CIDR
return False
return True
except: # not IP address
return True # IP地址合法
except:
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:
"""
@ -34,7 +39,7 @@ def isPort(port: int) -> bool:
不合法: return False
"""
try:
if 1 <= port <= 65535:
if 1 <= port <= 65535: # 1 ~ 65535
return True
except: # illegal
pass

8
ProxyFilter/filter.py

@ -4,7 +4,7 @@
from ProxyFilter import Shadowsocks
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, {
'...': '...',
'type': '...',
'...': '...',
...
}
@ -22,9 +22,9 @@ def filte(raw: dict) -> tuple[bool, str]:
if 'type' not in raw:
return False, 'Missing `type` option'
if raw['type'] == 'ss':
return Shadowsocks.ssFilter(raw)
return Shadowsocks.ssFilter(raw, isExtra)
elif raw['type'] == 'ssr':
return ShadowsocksR.ssrFilter(raw)
return ShadowsocksR.ssrFilter(raw, isExtra)
else:
return False, 'Unknown proxy type'
except:

2
Web.py

@ -71,7 +71,7 @@ def addCheckTask(checkList: dict, proxyList: dict, priority: str, userId: str) -
proxyList[i] = Decoder.decode(proxyList[i]) # 解码分享链接
if proxyList[i] is None:
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: # 节点不合法
return genError('index ' + str(i) + ': ' + proxyList[i])

31
docs/ProxyObject.md

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

Loading…
Cancel
Save