mirror of https://github.com/dnomd343/ProxyC
Dnomd343
3 years ago
4 changed files with 268 additions and 138 deletions
@ -0,0 +1,142 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# -*- coding:utf-8 -*- |
||||
|
|
||||
|
import re |
||||
|
import json |
||||
|
from ProxyDecoder import baseFunc |
||||
|
|
||||
|
def __splitEdParam(path: str) -> tuple[int or None, str]: # 分离early-data参数 |
||||
|
if path.find('?') == -1: |
||||
|
return None, path |
||||
|
content = re.search(r'^([\s\S]*?)\?([\s\S]*)$', path) |
||||
|
ed = None |
||||
|
params = [] |
||||
|
for field in content[2].split('&'): # ?param_a=...¶m_b=... |
||||
|
if not field.startswith('ed='): |
||||
|
params.append(field) |
||||
|
continue |
||||
|
ed = int(field[3:]) # ed=... |
||||
|
if ed is None: # ed param not found |
||||
|
return None, path |
||||
|
if not params: # param -> [] |
||||
|
return ed, content[1] |
||||
|
return ed, content[1] + '?' + '&'.join(params) |
||||
|
|
||||
|
def __vmessV2raynDecode(url: str) -> dict: |
||||
|
""" |
||||
|
v2rayN / v2rayNG分享链接解码 |
||||
|
|
||||
|
FORMAT: vmess://BASE64-ENCODED-JSON-STRING |
||||
|
|
||||
|
{ |
||||
|
"v": "2", |
||||
|
"ps": "...", |
||||
|
"add": "...", |
||||
|
"port": "...", |
||||
|
"id": "...", |
||||
|
"aid": "...", |
||||
|
"scy": "...", |
||||
|
"net": "...", |
||||
|
"type": "...", |
||||
|
"host": "...", |
||||
|
"path": "...", |
||||
|
"tls": "...", |
||||
|
"sni": "...", |
||||
|
"alpn": "..." |
||||
|
} |
||||
|
""" |
||||
|
content = json.loads( |
||||
|
baseFunc.base64Decode( |
||||
|
re.search(r'^vmess://([\S]+)$', url).group(1) # vmess://{base64} |
||||
|
) |
||||
|
) |
||||
|
if int(content['v']) != 2: # version => 2 |
||||
|
raise Exception('Unknown version field') |
||||
|
info = { |
||||
|
'server': content['add'], |
||||
|
'port': int(content['port']), |
||||
|
'id': content['id'], |
||||
|
'aid': int(content['aid']), |
||||
|
} |
||||
|
if 'ps' in content: # ps -> remark |
||||
|
info['remark'] = content['ps'] |
||||
|
if 'scy' in content: # scy -> method |
||||
|
info['method'] = content['scy'] |
||||
|
stream = { |
||||
|
'type': content['net'] # net -> stream.type |
||||
|
} |
||||
|
if content['net'] == 'tcp': |
||||
|
if 'http' in content and content['type'] == 'http': # type -> none / http |
||||
|
stream['obfs'] = { |
||||
|
'host': content['host'], |
||||
|
'path': content['path'] |
||||
|
} |
||||
|
elif content['net'] == 'kcp': |
||||
|
if 'type' in content: |
||||
|
stream['obfs'] = content['type'] |
||||
|
if 'path' in content: |
||||
|
stream['seed'] = content['path'] # path -> seed |
||||
|
elif content['net'] == 'ws': |
||||
|
if 'host' in content: |
||||
|
stream['host'] = content['host'] |
||||
|
if 'path' in content: |
||||
|
try: |
||||
|
stream['ed'], stream['path'] = __splitEdParam(content['path']) |
||||
|
except: |
||||
|
stream['path'] = content['path'] |
||||
|
elif content['net'] == 'h2': |
||||
|
if 'host' in content: |
||||
|
stream['host'] = content['host'] |
||||
|
if 'path' in content: |
||||
|
stream['path'] = content['path'] |
||||
|
elif content['net'] == 'quic': |
||||
|
if 'type' in content: |
||||
|
stream['obfs'] = content['type'] |
||||
|
if 'host' in content: |
||||
|
stream['method'] = content['host'] |
||||
|
if 'path' in content: |
||||
|
stream['passwd'] = content['path'] |
||||
|
elif content['net'] == 'grpc': |
||||
|
if 'type' in content and content['type'] == 'multi': |
||||
|
stream['mode'] = 'multi' |
||||
|
if 'path' in content: |
||||
|
stream['service'] = content['path'] |
||||
|
else: |
||||
|
raise Exception('Unknown network type') |
||||
|
|
||||
|
secure = None |
||||
|
if 'tls' in content and content['tls'] == 'tls': # enable TLS |
||||
|
secure = {} |
||||
|
if 'sni' in content: |
||||
|
secure['sni'] = content['sni'] # sni option |
||||
|
if 'alpn' in content: |
||||
|
if content['alpn'] == '': |
||||
|
secure['alpn'] = None # ignore alpn option |
||||
|
else: |
||||
|
secure['alpn'] = content['alpn'] # h2 | http/1.1 | h2,http/1.1 |
||||
|
|
||||
|
stream['secure'] = secure |
||||
|
info['stream'] = stream |
||||
|
return info |
||||
|
|
||||
|
def vmessDecode(url: str) -> dict or None: |
||||
|
""" |
||||
|
VMess分享链接解码 |
||||
|
|
||||
|
链接合法: |
||||
|
return { |
||||
|
'type': 'vmess', |
||||
|
... |
||||
|
} |
||||
|
|
||||
|
链接不合法: |
||||
|
return None |
||||
|
""" |
||||
|
if url[0:8] != 'vmess://': |
||||
|
return None |
||||
|
try: |
||||
|
result = __vmessV2raynDecode(url) # try v2rayN decode |
||||
|
except: |
||||
|
return None |
||||
|
result['type'] = 'vmess' |
||||
|
return result |
Loading…
Reference in new issue