Browse Source

feat: shadowsocks plain url decode

dev
dnomd343 2 years ago
parent
commit
5a9544dc9e
  1. 5
      Basis/Exception.py
  2. 9
      Basis/Functions.py
  3. 40
      Decoder/Shadowsocks.py
  4. 14
      test.py

5
Basis/Exception.py

@ -24,3 +24,8 @@ class managerException(Exception): # for manager error
class checkException(Exception): # for check error
def __init__(self, reason):
self.reason = reason
class decodeException(Exception): # for url decode
def __init__(self, reason):
self.reason = reason

9
Basis/Functions.py

@ -8,6 +8,7 @@ import psutil
import random
import hashlib
from IPy import IP
import urllib.parse
from Basis.Logger import logging
@ -111,6 +112,14 @@ def toBool(raw) -> bool:
raise RuntimeError('Unable convert to bool')
def urlEncode(content: str) -> str:
return urllib.parse.urlencode(content)
def urlDecode(content: str) -> str:
return urllib.parse.unquote(content)
def getAvailablePort(rangeStart: int = 1024, rangeEnd: int = 65535, waitTime: int = 10) -> int: # get available port
if rangeStart > rangeEnd or rangeStart < 1 or rangeEnd > 65535:
raise RuntimeError('Invalid port range')

40
Decoder/Shadowsocks.py

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SIP002: https://shadowsocks.org/guide/sip002.html
# Plain / Common: https://shadowsocks.org/guide/configs.html#uri-and-qr-code
from Basis.Logger import logging
from Basis.Functions import urlDecode
from Basis.Exception import decodeException
def ssBasicConfig() -> dict: # load shadowsocks basic config
return {
'type': 'ss',
'info': {}
}
def ssPlain(url: str, spaceRemark: bool = True) -> dict:
"""
FORMAT: ss://method:password@hostname:port#TAG
"""
config = ssBasicConfig()
logging.debug('Shadowsocks plain decode -> %s' % url)
if not url.startswith('ss://'):
logging.debug('Shadowsocks url should start with `ss://`')
raise decodeException('Shadowsocks prefix error')
url = url[5:] # remove `ss://`
if '#' in url:
url, remark = url.rsplit('#', 1) # split remark
if spaceRemark: # use `+` instead of space
remark = remark.replace('+', ' ')
config['name'] = urlDecode(remark)
logging.debug('Shadowsocks url remark -> %s' % config['name'])
userinfo, url = url.rsplit('@', 1)
config['info']['server'], config['info']['port'] = url.rsplit(':', 1)
config['info']['method'], config['info']['passwd'] = userinfo.split(':', 1)
logging.debug('Shadowsocks plain release -> %s', config)
return config

14
test.py

@ -0,0 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Basis import Constant
Constant.LogLevel = 'DEBUG'
from Basis.Logger import logging
from pprint import pprint
from Filter import Filter
from Decoder import Shadowsocks
ret = Shadowsocks.ssPlain('ss://aes-128-ctr:password@8.210.148.24:34326')
ret = Filter(ret['type'], ret['info'])
pprint(ret, sort_dicts = False)
Loading…
Cancel
Save