Parse SS URL with much cleaner URL struct methods

This commit is contained in:
Rainux Luo
2017-01-07 06:54:31 +08:00
parent 97801c4ee6
commit faf029c7f7
4 changed files with 34 additions and 64 deletions

View File

@ -11,6 +11,4 @@
void ScanQRCodeOnScreen();
NSDictionary<NSString *, id>* ParseSSURL(NSURL* url);
#endif /* QRCodeUtils_h */

View File

@ -71,63 +71,3 @@ void ScanQRCodeOnScreen() {
}
];
}
// SS URLServerProfiledict
NSDictionary<NSString *, id>* ParseSSURL(NSURL* url) {
if (!url.host) {
return nil;
}
NSString *urlString = [url absoluteString];
int i = 0;
NSString *errorReason = nil;
while(i < 2) {
if (i == 1) {
NSString* host = url.host;
if ([host length]%4!=0) {
int n = 4 - [host length]%4;
if (1==n) {
host = [host stringByAppendingString:@"="];
} else if (2==n) {
host = [host stringByAppendingString:@"=="];
}
}
NSData *data = [[NSData alloc] initWithBase64EncodedString:host options:0];
NSString *decodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
urlString = decodedString;
}
i++;
urlString = [urlString stringByReplacingOccurrencesOfString:@"ss://" withString:@"" options:NSAnchoredSearch range:NSMakeRange(0, urlString.length)];
NSRange firstColonRange = [urlString rangeOfString:@":"];
NSRange lastColonRange = [urlString rangeOfString:@":" options:NSBackwardsSearch];
NSRange lastAtRange = [urlString rangeOfString:@"@" options:NSBackwardsSearch];
if (firstColonRange.length == 0) {
errorReason = @"colon not found";
continue;
}
if (firstColonRange.location == lastColonRange.location) {
errorReason = @"only one colon";
continue;
}
if (lastAtRange.length == 0) {
errorReason = @"at not found";
continue;
}
if (!((firstColonRange.location < lastAtRange.location) && (lastAtRange.location < lastColonRange.location))) {
errorReason = @"wrong position";
continue;
}
NSString *method = [urlString substringWithRange:NSMakeRange(0, firstColonRange.location)];
NSString *password = [urlString substringWithRange:NSMakeRange(firstColonRange.location + 1, lastAtRange.location - firstColonRange.location - 1)];
NSString *IP = [urlString substringWithRange:NSMakeRange(lastAtRange.location + 1, lastColonRange.location - lastAtRange.location - 1)];
NSString *port = [urlString substringWithRange:NSMakeRange(lastColonRange.location + 1, urlString.length - lastColonRange.location - 1)];
return @{@"ServerHost": IP,
@"ServerPort": @([port integerValue]),
@"Method": method,
@"Password": password,
};
}
return nil;
}

View File

@ -8,14 +8,12 @@
import Foundation
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
}
extension Data {
func sha1() -> String {
let data = self
@ -25,3 +23,36 @@ extension Data {
return hexBytes.joined(separator: "")
}
}
func ParseSSURL(_ url: URL?) -> [String: Any?]? {
func padBase64(string: String) -> String {
var length = string.characters.count
length = 4 - length % 4 + length
return string.padding(toLength: length, withPad: "=", startingAt: 0)
}
if url?.host == nil {
return nil
}
var plainUrl: URL! = url
let data = Data(base64Encoded: padBase64(string: url!.host!),
options: Data.Base64DecodingOptions())
if data != nil {
let decoded = String(data: data!, encoding: String.Encoding.utf8)
plainUrl = URL(string: "ss://\(decoded!)")
if plainUrl == nil {
return nil
}
}
return ["ServerHost": plainUrl.host,
"ServerPort": UInt16(plainUrl.port!),
"Method": plainUrl.user,
"Password": plainUrl.password,
]
}

View File

@ -7,6 +7,7 @@
//
import XCTest
@testable import ShadowsocksX_NG
class UtilsTests: XCTestCase {