Parse SS URL with much cleaner URL struct methods
This commit is contained in:
@ -11,6 +11,4 @@
|
||||
|
||||
void ScanQRCodeOnScreen();
|
||||
|
||||
NSDictionary<NSString *, id>* ParseSSURL(NSURL* url);
|
||||
|
||||
#endif /* QRCodeUtils_h */
|
||||
|
@ -71,63 +71,3 @@ void ScanQRCodeOnScreen() {
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
// 解析SS URL,如果成功则返回一个与ServerProfile类兼容的dict
|
||||
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;
|
||||
}
|
||||
|
@ -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,
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user