diff --git a/parser/shadowsocks.go b/parser/shadowsocks.go index a4f356f..09d3c91 100644 --- a/parser/shadowsocks.go +++ b/parser/shadowsocks.go @@ -15,7 +15,24 @@ func ParseShadowsocks(proxy string) (model.Outbound, error) { if !strings.HasPrefix(proxy, constant.ShadowsocksPrefix) { return model.Outbound{}, &ParseError{Type: ErrInvalidPrefix, Raw: proxy} } - + needDecode := true + if !strings.Contains(proxy, "@") { + s := strings.SplitN(proxy, "#", 2) + d, err := util.DecodeBase64(strings.TrimPrefix(s[0], "ss://")) + if err != nil { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "url parse error", + Raw: proxy, + } + } + if len(s) == 2 { + proxy = "ss://" + d + "#" + s[1] + } else { + proxy = "ss://" + d + } + needDecode = false + } link, err := url.Parse(proxy) if err != nil { return model.Outbound{}, &ParseError{ @@ -50,32 +67,38 @@ func ParseShadowsocks(proxy string) (model.Outbound, error) { } } - user, err := util.DecodeBase64(link.User.Username()) - if err != nil { - return model.Outbound{}, &ParseError{ - Type: ErrInvalidStruct, - Message: "missing method and password", - Raw: proxy, + method := "" + password := "" + if needDecode { + user, err := util.DecodeBase64(link.User.Username()) + if err != nil { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "missing method and password", + Raw: proxy, + } } - } - - if user == "" { - return model.Outbound{}, &ParseError{ - Type: ErrInvalidStruct, - Message: "missing method and password", - Raw: proxy, + 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, + methodAndPass := strings.SplitN(user, ":", 2) + if len(methodAndPass) != 2 { + return model.Outbound{}, &ParseError{ + Type: ErrInvalidStruct, + Message: "missing method and password", + Raw: proxy, + } } + method = methodAndPass[0] + password = methodAndPass[1] + } else { + method = link.User.Username() + password, _ = link.User.Password() } - method := methodAndPass[0] - password := methodAndPass[1] query := link.Query() pluginStr := query.Get("plugin")