| 73 | } |
| 74 | |
| 75 | func ParseSSLink(link string) (*Shadowsocks, error) { |
| 76 | if !strings.HasPrefix(link, "ss://") { |
| 77 | return nil, ErrorNotSSRLink |
| 78 | } |
| 79 | |
| 80 | uri, err := url.Parse(link) |
| 81 | if err != nil { |
| 82 | return nil, ErrorNotSSLink |
| 83 | } |
| 84 | |
| 85 | cipher := "" |
| 86 | password := "" |
| 87 | if uri.User.String() == "" { |
| 88 | // base64的情况 |
| 89 | infos, err := tool.Base64DecodeString(uri.Hostname()) |
| 90 | if err != nil { |
| 91 | return nil, err |
| 92 | } |
| 93 | uri, err = url.Parse("ss://" + infos) |
| 94 | if err != nil { |
| 95 | return nil, err |
| 96 | } |
| 97 | cipher = uri.User.Username() |
| 98 | password, _ = uri.User.Password() |
| 99 | } else { |
| 100 | cipherInfoString, err := tool.Base64DecodeString(uri.User.Username()) |
| 101 | if err != nil { |
| 102 | return nil, ErrorPasswordParseFail |
| 103 | } |
| 104 | cipherInfo := strings.SplitN(cipherInfoString, ":", 2) |
| 105 | if len(cipherInfo) < 2 { |
| 106 | return nil, ErrorPasswordParseFail |
| 107 | } |
| 108 | cipher = strings.ToLower(cipherInfo[0]) |
| 109 | password = cipherInfo[1] |
| 110 | } |
| 111 | server := uri.Hostname() |
| 112 | port, _ := strconv.Atoi(uri.Port()) |
| 113 | |
| 114 | moreInfos := uri.Query() |
| 115 | pluginString := moreInfos.Get("plugin") |
| 116 | plugin := "" |
| 117 | pluginOpts := make(map[string]interface{}) |
| 118 | if strings.Contains(pluginString, ";") { |
| 119 | pluginInfos, err := url.ParseQuery(pluginString) |
| 120 | if err == nil { |
| 121 | if strings.Contains(pluginString, "obfs") { |
| 122 | plugin = "obfs" |
| 123 | pluginOpts["mode"] = pluginInfos.Get("obfs") |
| 124 | pluginOpts["host"] = pluginInfos.Get("obfs-host") |
| 125 | } else if strings.Contains(pluginString, "v2ray") { |
| 126 | plugin = "v2ray-plugin" |
| 127 | pluginOpts["mode"] = pluginInfos.Get("mode") |
| 128 | pluginOpts["host"] = pluginInfos.Get("host") |
| 129 | pluginOpts["tls"] = strings.Contains(pluginString, "tls") |
| 130 | } |
| 131 | } |
| 132 | } |