mirror of
https://github.com/nitezs/sub2sing-box.git
synced 2024-12-23 11:24:43 -05:00
✨ 兼容shadowsocks的plugin (#8)
This commit is contained in:
parent
9e50b30af6
commit
7792c99f19
@ -2,6 +2,7 @@ package parser
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sub2sing-box/constant"
|
||||
"sub2sing-box/model"
|
||||
@ -9,90 +10,78 @@ import (
|
||||
)
|
||||
|
||||
func ParseShadowsocks(proxy string) (model.Outbound, error) {
|
||||
if !strings.HasPrefix(proxy, constant.ShadowsocksPrefix) {
|
||||
link, err := url.Parse(proxy)
|
||||
if err != nil {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "url parse error",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
server := link.Hostname()
|
||||
if server == "" {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing server host",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
if link.Scheme+"://" != constant.ShadowsocksPrefix {
|
||||
return model.Outbound{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy}
|
||||
}
|
||||
|
||||
proxy = strings.TrimPrefix(proxy, constant.ShadowsocksPrefix)
|
||||
urlParts := strings.SplitN(proxy, "@", 2)
|
||||
if len(urlParts) != 2 {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing character '@' in url",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
if !strings.Contains(urlParts[0], ":") {
|
||||
decoded, err := util.DecodeBase64(urlParts[0])
|
||||
if err != nil {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "invalid base64 encoded",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
urlParts[0] = decoded
|
||||
}
|
||||
credentials := strings.SplitN(urlParts[0], ":", 2)
|
||||
if len(credentials) != 2 {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing server host or port",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
method, password := credentials[0], credentials[1]
|
||||
|
||||
serverInfoAndTag := strings.SplitN(urlParts[1], "#", 2)
|
||||
serverAndPort := serverInfoAndTag[0]
|
||||
|
||||
lastColonIndex := strings.LastIndex(serverAndPort, ":")
|
||||
if lastColonIndex == -1 {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing port in address",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
server := serverAndPort[:lastColonIndex]
|
||||
portStr := serverAndPort[lastColonIndex+1:]
|
||||
|
||||
port, err := ParsePort(portStr)
|
||||
port, err := strconv.Atoi(link.Port())
|
||||
if err != nil {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidPort,
|
||||
Message: err.Error(),
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing server port",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
var remarks string
|
||||
if len(serverInfoAndTag) == 2 {
|
||||
unescape, err := url.QueryUnescape(serverInfoAndTag[1])
|
||||
if err != nil {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "cannot unescape remarks",
|
||||
Raw: proxy,
|
||||
}
|
||||
user, err := util.DecodeBase64(link.User.Username())
|
||||
if user == "" {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing method and password",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
methodAndPass := strings.SplitN(user, ":", 2)
|
||||
if len(methodAndPass) != 2 {
|
||||
return model.Outbound{}, &ParseError{
|
||||
Type: ErrInvalidStruct,
|
||||
Message: "missing method and password",
|
||||
Raw: proxy,
|
||||
}
|
||||
}
|
||||
|
||||
query := link.Query()
|
||||
pluginStr := query.Get("plugin")
|
||||
plugin := ""
|
||||
options := ""
|
||||
if pluginStr != "" {
|
||||
arr := strings.SplitN(pluginStr, ";", 2)
|
||||
if len(arr) == 2 {
|
||||
plugin = arr[0]
|
||||
options = arr[1]
|
||||
}
|
||||
remarks = strings.TrimSpace(unescape)
|
||||
} else {
|
||||
remarks = strings.TrimSpace(server + ":" + portStr)
|
||||
}
|
||||
|
||||
result := model.Outbound{
|
||||
Type: "shadowsocks",
|
||||
Tag: remarks,
|
||||
Tag: link.Fragment,
|
||||
ShadowsocksOptions: model.ShadowsocksOutboundOptions{
|
||||
ServerOptions: model.ServerOptions{
|
||||
Server: server,
|
||||
ServerPort: port,
|
||||
ServerPort: uint16(port),
|
||||
},
|
||||
Method: method,
|
||||
Password: password,
|
||||
Method: methodAndPass[0],
|
||||
Password: methodAndPass[1],
|
||||
Plugin: plugin,
|
||||
PluginOptions: options,
|
||||
},
|
||||
}
|
||||
return result, nil
|
||||
|
Loading…
Reference in New Issue
Block a user