|
| 1 | +// AltProxyFinder.m |
| 2 | +#import "AltProxyFinder.h" |
| 3 | +#import <CoreFoundation/CoreFoundation.h> |
| 4 | +#import <CFNetwork/CFNetwork.h> |
| 5 | + |
| 6 | +@implementation AltProxyFinder |
| 7 | + |
| 8 | ++ (instancetype)shared { |
| 9 | + static AltProxyFinder *sharedInstance = nil; |
| 10 | + static dispatch_once_t onceToken; |
| 11 | + dispatch_once(&onceToken, ^{ |
| 12 | + sharedInstance = [[AltProxyFinder alloc] init]; |
| 13 | + }); |
| 14 | + return sharedInstance; |
| 15 | +} |
| 16 | + |
| 17 | +- (NSString *)getProxyForDestinationUrl:(NSString *)destinationUrl destinationHost:(NSString *)destinationHost { |
| 18 | + NSDictionary *proxySettings = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings()); |
| 19 | + if (!proxySettings) { |
| 20 | + return @""; |
| 21 | + } |
| 22 | + |
| 23 | + NSNumber *pacEnabled = proxySettings[@"ProxyAutoConfigEnable"]; |
| 24 | + if ([pacEnabled intValue] == 1) { |
| 25 | + NSString *pacUrlString = proxySettings[@"ProxyAutoConfigURLString"]; |
| 26 | + if (pacUrlString) { |
| 27 | + NSURL *pacUrl = [NSURL URLWithString:pacUrlString]; |
| 28 | + if (pacUrl) { |
| 29 | + __block NSString *proxyUrl = @""; |
| 30 | + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); |
| 31 | + |
| 32 | + [[[NSURLSession sharedSession] dataTaskWithURL:pacUrl completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { |
| 33 | + if (data && !error) { |
| 34 | + NSString *pacContent = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; |
| 35 | + pacContent = [pacContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
| 36 | + if (![pacContent hasPrefix:@"<!DOCTYPE html>"]) { |
| 37 | + CFArrayRef proxyArray = CFNetworkCopyProxiesForAutoConfigurationScript((__bridge CFStringRef)pacContent, (__bridge CFURLRef)[NSURL URLWithString:destinationUrl], NULL); |
| 38 | + if (proxyArray && CFArrayGetCount(proxyArray) > 0) { |
| 39 | + NSDictionary *proxy = (__bridge NSDictionary *)CFArrayGetValueAtIndex(proxyArray, 0); |
| 40 | + NSString *type = proxy[(NSString *)kCFProxyTypeKey]; |
| 41 | + if ([type isEqualToString:(NSString *)kCFProxyTypeHTTP] || [type isEqualToString:(NSString *)kCFProxyTypeHTTPS]) { |
| 42 | + NSString *host = proxy[(NSString *)kCFProxyHostNameKey] ?: @"null"; |
| 43 | + NSNumber *port = proxy[(NSString *)kCFProxyPortNumberKey] ?: @(0); |
| 44 | + if (![host isEqualToString:@"null"] && [port intValue] != 0) { |
| 45 | + proxyUrl = [NSString stringWithFormat:@"http://%@:%@", host, port]; |
| 46 | + } |
| 47 | + } |
| 48 | + } |
| 49 | + if (proxyArray) CFRelease(proxyArray); |
| 50 | + } |
| 51 | + } |
| 52 | + dispatch_semaphore_signal(semaphore); |
| 53 | + }] resume]; |
| 54 | + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); |
| 55 | + return proxyUrl; |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + NSNumber *httpsEnable = proxySettings[@"HTTPSEnable"]; |
| 61 | + if ([httpsEnable intValue] == 1 && [destinationUrl hasPrefix:@"https"]) { |
| 62 | + NSString *host = proxySettings[@"HTTPSProxy"]; |
| 63 | + NSNumber *port = proxySettings[@"HTTPSPort"]; |
| 64 | + if (host && port) { |
| 65 | + return [NSString stringWithFormat:@"https://%@:%@", host, port]; |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + NSNumber *httpEnable = proxySettings[@"HTTPEnable"]; |
| 70 | + if ([httpEnable intValue] == 1) { |
| 71 | + NSString *host = proxySettings[@"HTTPProxy"]; |
| 72 | + NSNumber *port = proxySettings[@"HTTPPort"]; |
| 73 | + if (host && port) { |
| 74 | + return [NSString stringWithFormat:@"http://%@:%@", host, port]; |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + return @""; |
| 79 | +} |
| 80 | + |
| 81 | +@end |
0 commit comments