Skip to content

Commit b4cb8b5

Browse files
committed
fix: use Foundation Lib for executing pac
1 parent fd79236 commit b4cb8b5

1 file changed

Lines changed: 68 additions & 19 deletions

File tree

ios/Classes/SwiftFlutterSystemProxyPlugin.swift

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,77 @@ public class SwiftFlutterSystemProxyPlugin: NSObject, FlutterPlugin {
1111
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
1212
switch call.method {
1313
case "getDeviceProxy":
14-
let systemProxySettings = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() ?? [:] as CFDictionary
15-
result(systemProxySettings as NSDictionary)
16-
break
17-
case "executePAC":
18-
let systemProxySettings = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() ?? [:] as CFDictionary
19-
let proxyDict = systemProxySettings as NSDictionary
20-
if(proxyDict.value(forKey:"ProxyAutoConfigEnable")as! Bool){
21-
let args = call.arguments as! NSDictionary
22-
let url = args.value(forKey:"url") as! String
23-
let host = args.value(forKey:"host") as! String
24-
let js = args.value(forKey:"js") as! String
25-
let jsEngine:JSContext = JSContext()
26-
jsEngine.evaluateScript(js)
27-
let fn = "FindProxyForURL(\"" + url + "\",\""+host+"\")"
28-
let proxy = jsEngine.evaluateScript(fn)
29-
result(proxy?.toString())
30-
}else{
31-
result("DIRECT")
32-
}
14+
let args = call.arguments as! NSDictionary
15+
let url = args.value(forKey:"url") as! String
16+
var dict:[String:Any] = [:]
17+
findProxyFromEnvironment(url: url,callback: { host, port in
18+
dict["host"] = host
19+
dict["port"] = port
20+
result(dict)
21+
})
3322
break
3423
default:
3524
result(FlutterMethodNotImplemented)
3625
}
3726
}
27+
28+
func findProxyFromEnvironment(url: String,callback: @escaping (_ host:String?,_ port:Int?)->Void) {
29+
let proxConfigDict = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() as NSDictionary?
30+
if(proxConfigDict != nil){
31+
if(proxConfigDict!["ProxyAutoConfigEnable"] as? Int == 1){
32+
let pacUrl = proxConfigDict!["ProxyAutoConfigURLString"] as? String
33+
let pacContent = proxConfigDict!["ProxyAutoConfigJavaScript"] as? String
34+
if(pacContent != nil){
35+
self.handlePacContent(pacContent: pacContent! as String, url: url, callback: callback)
36+
}
37+
downloadPac(pacUrl: pacUrl!, callback: { pacContent,error in
38+
39+
if(error != nil){
40+
callback(nil,nil)
41+
}else{
42+
self.handlePacContent(pacContent: pacContent!, url: url, callback: callback)
43+
}
44+
})
45+
} else if (proxConfigDict!["HTTPEnable"] as? Int == 1){
46+
callback((proxConfigDict!["HTTPProxy"] as? String),(proxConfigDict!["HTTPPort"] as? Int))
47+
} else if ( proxConfigDict!["HTTPSEnable"] as? Int == 1){
48+
callback((proxConfigDict!["HTTPSProxy"] as? String),(proxConfigDict!["HTTPSPort"] as? Int))
49+
} else {
50+
callback(nil,nil)
51+
}
52+
}
53+
}
54+
55+
func handlePacContent(pacContent: String,url: String, callback:(_ host:String?,_ port:Int?)->Void){
56+
let proxies = CFNetworkCopyProxiesForAutoConfigurationScript(pacContent as CFString, CFURLCreateWithString(kCFAllocatorDefault, url as CFString, nil), nil)!.takeUnretainedValue() as? [[CFString: Any]] ?? [];
57+
if(proxies.count > 0){
58+
let proxy = proxies.first{$0[kCFProxyTypeKey] as! CFString == kCFProxyTypeHTTP || $0[kCFProxyTypeKey] as! CFString == kCFProxyTypeHTTPS}
59+
if(proxy != nil){
60+
let host = proxy?[kCFProxyHostNameKey] ?? nil
61+
let port = proxy?[kCFProxyPortNumberKey] ?? nil
62+
callback(host as? String,port as? Int)
63+
}else{
64+
callback(nil,nil)
65+
}
66+
}else{
67+
callback(nil,nil)
68+
}
69+
}
70+
71+
72+
func downloadPac(pacUrl:String, callback:@escaping (_ pacContent:String?,_ error: Error?)->Void) {
73+
var pacContent:String = ""
74+
let config = URLSessionConfiguration.default
75+
config.connectionProxyDictionary = [AnyHashable: Any]()
76+
let session = URLSession.init(configuration: config,delegate: nil,delegateQueue: OperationQueue.current)
77+
session.dataTask(with: URL(string: pacUrl)!, completionHandler: { data, response, error in
78+
if(error != nil){
79+
callback(nil,error)
80+
}
81+
pacContent = String(bytes: data!,encoding: String.Encoding.utf8)!
82+
callback(pacContent,nil)
83+
}).resume()
84+
85+
}
86+
3887
}

0 commit comments

Comments
 (0)