Skip to content

Commit 5875367

Browse files
Release 0.1.0 (#12)
* use Android Proxy Selector instead or env vars. * use minSDKVersion 31 in example * ios: use min platform version 11.0 for example * fix: use Foundation Lib for executing pac * return error string instead of "Error" * clean code * release 0.1.0 * update: Homepage * modify project details
1 parent b618c89 commit 5875367

File tree

12 files changed

+138
-129
lines changed

12 files changed

+138
-129
lines changed

android/src/main/java/com/browserstack/fluttersystemproxy/flutter_system_proxy/FlutterSystemProxyPlugin.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import androidx.annotation.NonNull;
44
import android.text.TextUtils;
55

6+
import java.net.InetSocketAddress;
7+
import java.net.Proxy;
8+
import java.net.ProxySelector;
9+
import java.net.URI;
610
import java.util.HashMap;
711
import java.util.Map;
812

@@ -31,12 +35,26 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBindin
3135
@Override
3236
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
3337
if (call.method.equals("getDeviceProxy")) {
34-
Map map = new HashMap<String, String>();
35-
map.put("http.proxyHost", System.getProperty("http.proxyHost"));
36-
map.put("http.proxyPort", System.getProperty("http.proxyPort"));
37-
map.put("https.proxyHost", System.getProperty("https.proxyHost"));
38-
map.put("https.proxyPort", System.getProperty("https.proxyPort"));
39-
result.success(map);
38+
HashMap<String, String> _map = new HashMap<String, String>() {
39+
{
40+
put("host", null);
41+
put("port", null);
42+
}
43+
};
44+
String url = call.argument("url");
45+
ProxySelector selector = ProxySelector.getDefault();
46+
try {
47+
for (Proxy proxy : selector.select(new URI(url))) {
48+
if (proxy.type() == Proxy.Type.HTTP) {
49+
InetSocketAddress addr = (InetSocketAddress) proxy.address();
50+
_map.put("host", addr.getHostName());
51+
_map.put("port", Integer.toString(addr.getPort()));
52+
}
53+
}
54+
result.success(_map);
55+
} catch (Exception ex) {
56+
result.error("URL Error",ex.getMessage(),null);
57+
}
4058
} else {
4159
result.notImplemented();
4260
}

example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
2525
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
2626

2727
android {
28-
compileSdkVersion 30
28+
compileSdkVersion 31
2929

3030
defaultConfig {
3131
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).

example/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
<key>CFBundleVersion</key>
2222
<string>1.0</string>
2323
<key>MinimumOSVersion</key>
24-
<string>8.0</string>
24+
<string>11.0</string>
2525
</dict>
2626
</plist>

example/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
# platform :ios, '9.0'
2+
platform :ios, '11.0'
33

44
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
55
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

example/ios/Podfile.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ EXTERNAL SOURCES:
1414
:path: ".symlinks/plugins/flutter_system_proxy/ios"
1515

1616
SPEC CHECKSUMS:
17-
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
17+
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
1818
flutter_system_proxy: 96eb97e3857a1d1bc533a6f7387a1f0dcb63d782
1919

20-
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
20+
PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d
2121

22-
COCOAPODS: 1.11.2
22+
COCOAPODS: 1.11.3

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 51;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -68,7 +68,6 @@
6868
3D695DD80D4DCA36C1B83028 /* Pods-Runner.release.xcconfig */,
6969
2B955829EF2302761365E6DB /* Pods-Runner.profile.xcconfig */,
7070
);
71-
name = Pods;
7271
path = Pods;
7372
sourceTree = "<group>";
7473
};
@@ -156,7 +155,7 @@
156155
97C146E61CF9000F007C117D /* Project object */ = {
157156
isa = PBXProject;
158157
attributes = {
159-
LastUpgradeCheck = 1020;
158+
LastUpgradeCheck = 1300;
160159
ORGANIZATIONNAME = "";
161160
TargetAttributes = {
162161
97C146ED1CF9000F007C117D = {
@@ -263,7 +262,7 @@
263262
);
264263
runOnlyForDeploymentPostprocessing = 0;
265264
shellPath = /bin/sh;
266-
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
265+
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
267266
};
268267
/* End PBXShellScriptBuildPhase section */
269268

@@ -340,7 +339,7 @@
340339
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
341340
GCC_WARN_UNUSED_FUNCTION = YES;
342341
GCC_WARN_UNUSED_VARIABLE = YES;
343-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
342+
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
344343
MTL_ENABLE_DEBUG_INFO = NO;
345344
SDKROOT = iphoneos;
346345
SUPPORTED_PLATFORMS = iphoneos;
@@ -358,8 +357,11 @@
358357
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
359358
ENABLE_BITCODE = NO;
360359
INFOPLIST_FILE = Runner/Info.plist;
361-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
362-
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxyExample;
360+
LD_RUNPATH_SEARCH_PATHS = (
361+
"$(inherited)",
362+
"@executable_path/Frameworks",
363+
);
364+
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxy;
363365
PRODUCT_NAME = "$(TARGET_NAME)";
364366
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
365367
SWIFT_VERSION = 5.0;
@@ -414,7 +416,7 @@
414416
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
415417
GCC_WARN_UNUSED_FUNCTION = YES;
416418
GCC_WARN_UNUSED_VARIABLE = YES;
417-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
419+
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
418420
MTL_ENABLE_DEBUG_INFO = YES;
419421
ONLY_ACTIVE_ARCH = YES;
420422
SDKROOT = iphoneos;
@@ -463,7 +465,7 @@
463465
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
464466
GCC_WARN_UNUSED_FUNCTION = YES;
465467
GCC_WARN_UNUSED_VARIABLE = YES;
466-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
468+
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
467469
MTL_ENABLE_DEBUG_INFO = NO;
468470
SDKROOT = iphoneos;
469471
SUPPORTED_PLATFORMS = iphoneos;
@@ -482,8 +484,11 @@
482484
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
483485
ENABLE_BITCODE = NO;
484486
INFOPLIST_FILE = Runner/Info.plist;
485-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
486-
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxyExample;
487+
LD_RUNPATH_SEARCH_PATHS = (
488+
"$(inherited)",
489+
"@executable_path/Frameworks",
490+
);
491+
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxy;
487492
PRODUCT_NAME = "$(TARGET_NAME)";
488493
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
489494
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -501,8 +506,11 @@
501506
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
502507
ENABLE_BITCODE = NO;
503508
INFOPLIST_FILE = Runner/Info.plist;
504-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
505-
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxyExample;
509+
LD_RUNPATH_SEARCH_PATHS = (
510+
"$(inherited)",
511+
"@executable_path/Frameworks",
512+
);
513+
PRODUCT_BUNDLE_IDENTIFIER = com.browserstack.fluttersystemproxy.flutterSystemProxy;
506514
PRODUCT_NAME = "$(TARGET_NAME)";
507515
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
508516
SWIFT_VERSION = 5.0;

example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1020"
3+
LastUpgradeVersion = "1300"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

example/ios/Runner/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>CADisableMinimumFrameDurationOnPhone</key>
6+
<true/>
57
<key>CFBundleDevelopmentRegion</key>
68
<string>$(DEVELOPMENT_LANGUAGE)</string>
79
<key>CFBundleExecutable</key>

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,6 @@ Future<String> fetchLocalHost() async {
9090
return response.toString();
9191
} catch (e) {
9292
print(e);
93-
return "Error";
93+
return e.toString();
9494
}
9595
}

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)