|
5 | 5 | using System.Web;
|
6 | 6 | using Shadowsocks.Controller;
|
7 | 7 | using System.Text.RegularExpressions;
|
| 8 | +using System.Linq; |
8 | 9 |
|
9 | 10 | namespace Shadowsocks.Model
|
10 | 11 | {
|
@@ -162,79 +163,81 @@ private static Server ParseLegacyURL(string ssURL)
|
162 | 163 | return server;
|
163 | 164 | }
|
164 | 165 |
|
165 |
| - public static List<Server> GetServers(string ssURL) |
| 166 | + public static Server ParseURL(string serverUrl) |
166 | 167 | {
|
167 |
| - var serverUrls = ssURL.Split('\r', '\n', ' '); |
| 168 | + string _serverUrl = serverUrl.Trim(); |
| 169 | + if (!_serverUrl.BeginWith("ss://", StringComparison.InvariantCultureIgnoreCase)) |
| 170 | + { |
| 171 | + return null; |
| 172 | + } |
168 | 173 |
|
169 |
| - List<Server> servers = new List<Server>(); |
170 |
| - foreach (string serverUrl in serverUrls) |
| 174 | + Server legacyServer = ParseLegacyURL(serverUrl); |
| 175 | + if (legacyServer != null) //legacy |
| 176 | + { |
| 177 | + return legacyServer; |
| 178 | + } |
| 179 | + else //SIP002 |
171 | 180 | {
|
172 |
| - string _serverUrl = serverUrl.Trim(); |
173 |
| - if (!_serverUrl.BeginWith("ss://", StringComparison.InvariantCultureIgnoreCase)) |
| 181 | + Uri parsedUrl; |
| 182 | + try |
174 | 183 | {
|
175 |
| - continue; |
| 184 | + parsedUrl = new Uri(serverUrl); |
176 | 185 | }
|
177 |
| - |
178 |
| - Server legacyServer = ParseLegacyURL(serverUrl); |
179 |
| - if (legacyServer != null) //legacy |
| 186 | + catch (UriFormatException) |
180 | 187 | {
|
181 |
| - servers.Add(legacyServer); |
| 188 | + return null; |
182 | 189 | }
|
183 |
| - else //SIP002 |
| 190 | + Server server = new Server |
184 | 191 | {
|
185 |
| - Uri parsedUrl; |
186 |
| - try |
187 |
| - { |
188 |
| - parsedUrl = new Uri(serverUrl); |
189 |
| - } |
190 |
| - catch (UriFormatException) |
191 |
| - { |
192 |
| - continue; |
193 |
| - } |
194 |
| - Server server = new Server |
195 |
| - { |
196 |
| - remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), |
197 |
| - server = parsedUrl.IdnHost, |
198 |
| - server_port = parsedUrl.Port, |
199 |
| - }; |
200 |
| - |
201 |
| - // parse base64 UserInfo |
202 |
| - string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped); |
203 |
| - string base64 = rawUserInfo.Replace('-', '+').Replace('_', '/'); // Web-safe base64 to normal base64 |
204 |
| - string userInfo = ""; |
205 |
| - try |
206 |
| - { |
207 |
| - userInfo = Encoding.UTF8.GetString(Convert.FromBase64String( |
208 |
| - base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))); |
209 |
| - } |
210 |
| - catch (FormatException) |
211 |
| - { |
212 |
| - continue; |
213 |
| - } |
214 |
| - string[] userInfoParts = userInfo.Split(new char[] { ':' }, 2); |
215 |
| - if (userInfoParts.Length != 2) |
216 |
| - { |
217 |
| - continue; |
218 |
| - } |
219 |
| - server.method = userInfoParts[0]; |
220 |
| - server.password = userInfoParts[1]; |
221 |
| - |
222 |
| - NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query); |
223 |
| - string[] pluginParts = (queryParameters["plugin"] ?? "").Split(new[] { ';' }, 2); |
224 |
| - if (pluginParts.Length > 0) |
225 |
| - { |
226 |
| - server.plugin = pluginParts[0] ?? ""; |
227 |
| - } |
| 192 | + remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped), |
| 193 | + server = parsedUrl.IdnHost, |
| 194 | + server_port = parsedUrl.Port, |
| 195 | + }; |
| 196 | + |
| 197 | + // parse base64 UserInfo |
| 198 | + string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped); |
| 199 | + string base64 = rawUserInfo.Replace('-', '+').Replace('_', '/'); // Web-safe base64 to normal base64 |
| 200 | + string userInfo = ""; |
| 201 | + try |
| 202 | + { |
| 203 | + userInfo = Encoding.UTF8.GetString(Convert.FromBase64String( |
| 204 | + base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '='))); |
| 205 | + } |
| 206 | + catch (FormatException) |
| 207 | + { |
| 208 | + return null; |
| 209 | + } |
| 210 | + string[] userInfoParts = userInfo.Split(new char[] { ':' }, 2); |
| 211 | + if (userInfoParts.Length != 2) |
| 212 | + { |
| 213 | + return null; |
| 214 | + } |
| 215 | + server.method = userInfoParts[0]; |
| 216 | + server.password = userInfoParts[1]; |
228 | 217 |
|
229 |
| - if (pluginParts.Length > 1) |
230 |
| - { |
231 |
| - server.plugin_opts = pluginParts[1] ?? ""; |
232 |
| - } |
| 218 | + NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query); |
| 219 | + string[] pluginParts = (queryParameters["plugin"] ?? "").Split(new[] { ';' }, 2); |
| 220 | + if (pluginParts.Length > 0) |
| 221 | + { |
| 222 | + server.plugin = pluginParts[0] ?? ""; |
| 223 | + } |
233 | 224 |
|
234 |
| - servers.Add(server); |
| 225 | + if (pluginParts.Length > 1) |
| 226 | + { |
| 227 | + server.plugin_opts = pluginParts[1] ?? ""; |
235 | 228 | }
|
| 229 | + |
| 230 | + return server; |
236 | 231 | }
|
237 |
| - return servers; |
| 232 | + } |
| 233 | + |
| 234 | + public static List<Server> GetServers(string ssURL) |
| 235 | + { |
| 236 | + return ssURL |
| 237 | + .Split('\r', '\n', ' ') |
| 238 | + .Select(u => ParseURL(u)) |
| 239 | + .Where(s => s != null) |
| 240 | + .ToList(); |
238 | 241 | }
|
239 | 242 |
|
240 | 243 | public string Identifier()
|
|
0 commit comments