diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7d94389..5e2ce8f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -37,6 +37,14 @@
+
+
+
+
+
+
+ exitProcess(0)
+ }
+ .setCancelable(false)
+ .create()
+ dialog.show()
+ }
+
+}
\ No newline at end of file
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
index 329d614..3c2b0e8 100644
--- a/ios/Runner/AppDelegate.swift
+++ b/ios/Runner/AppDelegate.swift
@@ -10,13 +10,6 @@ import NetworkExtension
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
-// let url = URL(string: "http://www.baidu.com")!
-// let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
-// guard let data = data else { return }
-// print(String(data: data, encoding: .utf8)!)
-// }
-// task.resume()
-
let controller: FlutterViewController = window.rootViewController as! FlutterViewController ;
let batteryChannel = FlutterMethodChannel.init(name: "com.proxy/proxyVpn", binaryMessenger: controller as! FlutterBinaryMessenger);
batteryChannel.setMethodCallHandler({
@@ -54,14 +47,11 @@ import NetworkExtension
}
}
- var backgroundUpdateTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0)
- func endBackgroundUpdateTask() {
- AudioManager.shared.openBackgroundAudioAutoplay = false
- UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
- self.backgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
- }
-
override func applicationWillResignActive(_ application: UIApplication) {
+ if (!VpnManager.shared.isRunning()) {
+ return
+ }
+
AudioManager.shared.openBackgroundAudioAutoplay = true
self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
@@ -69,7 +59,17 @@ import NetworkExtension
}
override func applicationDidBecomeActive(_ application: UIApplication) {
self.endBackgroundUpdateTask()
-
+ }
+
+ var backgroundUpdateTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier(rawValue: 0)
+ func endBackgroundUpdateTask() {
+ if (!VpnManager.shared.isRunning()) {
+ return
+ }
+
+ AudioManager.shared.openBackgroundAudioAutoplay = false
+ UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
+ self.backgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
}
}
diff --git a/ios/Runner/VpnManager.swift b/ios/Runner/VpnManager.swift
index 381c8a0..7840898 100755
--- a/ios/Runner/VpnManager.swift
+++ b/ios/Runner/VpnManager.swift
@@ -169,5 +169,9 @@ extension VpnManager{
}
}
+
+ func isRunning() -> Bool {
+ return vpnStatus == VPNStatus.on
+ }
}
diff --git a/lib/main.dart b/lib/main.dart
index 6c9e9d9..223eb03 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,6 +4,7 @@ import 'dart:io';
import 'package:chinese_font_library/chinese_font_library.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/ui/component/split_view.dart';
import 'package:network_proxy/ui/content/body.dart';
@@ -20,11 +21,6 @@ import 'network/handler.dart';
import 'network/http/http.dart';
void main(List args) async {
- if (Platforms.isMobile()) {
- runApp(const FluentApp(MobileHomePage()));
- return;
- }
-
//多窗口
if (args.firstOrNull == 'multi_window') {
final windowId = int.parse(args[1]);
@@ -34,6 +30,13 @@ void main(List args) async {
}
WidgetsFlutterBinding.ensureInitialized();
+
+ var configuration = Configuration.instance;
+ if (Platforms.isMobile()) {
+ runApp(FluentApp(MobileHomePage(configuration: (await configuration))));
+ return;
+ }
+
await windowManager.ensureInitialized();
//设置窗口大小
WindowOptions windowOptions = WindowOptions(
@@ -46,7 +49,7 @@ void main(List args) async {
await windowManager.focus();
});
- runApp(const FluentApp(DesktopHomePage()));
+ runApp(FluentApp(DesktopHomePage(configuration: (await configuration))));
}
///多窗口
@@ -104,7 +107,9 @@ class FluentApp extends StatelessWidget {
}
class DesktopHomePage extends StatefulWidget {
- const DesktopHomePage({super.key});
+ final Configuration configuration;
+
+ const DesktopHomePage({super.key, required this.configuration});
@override
State createState() => _DesktopHomePagePageState();
@@ -129,13 +134,10 @@ class _DesktopHomePagePageState extends State implements EventL
@override
void initState() {
super.initState();
- proxyServer = ProxyServer(listener: this);
+ proxyServer = ProxyServer(widget.configuration, listener: this);
panel = NetworkTabController(tabStyle: const TextStyle(fontSize: 18), proxyServer: proxyServer);
- proxyServer.initializedListener(() {
- if (!proxyServer.guide) {
- return;
- }
+ if (widget.configuration.guide) {
//首次引导
showDialog(
context: context,
@@ -145,8 +147,8 @@ class _DesktopHomePagePageState extends State implements EventL
actions: [
TextButton(
onPressed: () {
- proxyServer.guide = false;
- proxyServer.flushConfig();
+ widget.configuration.guide = false;
+ widget.configuration.flushConfig();
Navigator.pop(context);
},
child: const Text('关闭'))
@@ -155,7 +157,9 @@ class _DesktopHomePagePageState extends State implements EventL
content: const Text('默认不会开启HTTPS抓包,请安装证书后再开启HTTPS抓包。\n'
'点击的HTTPS抓包(加锁图标),选择安装根证书,按照提示操作即可。'));
});
- });
+
+ return;
+ }
}
@override
diff --git a/lib/network/bin/configuration.dart b/lib/network/bin/configuration.dart
new file mode 100644
index 0000000..9f21a41
--- /dev/null
+++ b/lib/network/bin/configuration.dart
@@ -0,0 +1,142 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:network_proxy/network/util/host_filter.dart';
+import 'package:network_proxy/network/util/logger.dart';
+import 'package:network_proxy/network/util/request_rewrite.dart';
+import 'package:network_proxy/utils/platform.dart';
+import 'package:path_provider/path_provider.dart';
+
+class Configuration {
+ int port = 9099;
+
+ //是否启用https抓包
+ bool enableSsl = false;
+
+ //是否启用桌面抓包
+ bool enableDesktop = true;
+
+ //是否引导
+ bool guide = false;
+
+ //是否显示更新内容公告
+ bool upgradeNotice = true;
+
+ //请求重写
+ RequestRewrites requestRewrites = RequestRewrites();
+
+ Configuration._();
+
+ /// 单例
+ static Configuration? _instance;
+
+ static Future get instance async {
+ if (_instance == null) {
+ Configuration configuration = Configuration._();
+ await configuration.initConfig();
+ _instance = configuration;
+ }
+ return _instance!;
+ }
+
+ /// 初始化配置
+ Future initConfig() async {
+ // 读取配置文件
+ await _loadConfig();
+ }
+
+ Future homeDir() async {
+ String? userHome;
+ if (Platforms.isDesktop()) {
+ userHome = Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
+ } else {
+ userHome = (await getApplicationSupportDirectory()).path;
+ }
+
+ var separator = Platform.pathSeparator;
+ return File("${userHome!}$separator.proxypin");
+ }
+
+ /// 配置文件
+ Future configFile() async {
+ var separator = Platform.pathSeparator;
+ var home = await homeDir();
+ return File("${home.path}${separator}config.cnf");
+ }
+
+ /// 刷新配置文件
+ flushConfig() async {
+ var file = await configFile();
+ var exists = await file.exists();
+ if (!exists) {
+ file = await file.create(recursive: true);
+ }
+ HostFilter.whitelist.toJson();
+ HostFilter.blacklist.toJson();
+ var json = jsonEncode(toJson());
+ logger.i('刷新配置文件 $runtimeType ${toJson()}');
+ file.writeAsString(json);
+ }
+
+ /// 加载配置文件
+ Future _loadConfig() async {
+ var file = await configFile();
+ var exits = await file.exists();
+ if (!exits) {
+ guide = true;
+ return;
+ }
+
+ Map config = jsonDecode(await file.readAsString());
+ logger.i('加载配置文件 [$file]');
+ port = config['port'] ?? port;
+ enableSsl = config['enableSsl'] == true;
+ enableDesktop = config['enableDesktop'] ?? true;
+ guide = config['guide'] ?? false;
+ upgradeNotice = config['upgradeNotice'] ?? true;
+ HostFilter.whitelist.load(config['whitelist']);
+ HostFilter.blacklist.load(config['blacklist']);
+
+ await _loadRequestRewriteConfig();
+ }
+
+ /// 加载请求重写配置文件
+ Future _loadRequestRewriteConfig() async {
+ var home = await homeDir();
+ var file = File('${home.path}${Platform.pathSeparator}request_rewrite.json');
+ var exits = await file.exists();
+ if (!exits) {
+ return;
+ }
+
+ Map config = jsonDecode(await file.readAsString());
+
+ logger.i('加载请求重写配置文件 [$file]');
+ requestRewrites.load(config);
+ }
+
+ /// 保存请求重写配置文件
+ flushRequestRewriteConfig() async {
+ var home = await homeDir();
+ var file = File('${home.path}${Platform.pathSeparator}request_rewrite.json');
+ bool exists = await file.exists();
+ if (!exists) {
+ await file.create(recursive: true);
+ }
+ var json = jsonEncode(requestRewrites.toJson());
+ logger.i('刷新请求重写配置文件 ${file.path}');
+ file.writeAsString(json);
+ }
+
+ Map toJson() {
+ return {
+ 'guide': guide,
+ 'upgradeNotice': upgradeNotice,
+ 'port': port,
+ 'enableSsl': enableSsl,
+ 'enableDesktop': enableDesktop,
+ 'whitelist': HostFilter.whitelist.toJson(),
+ 'blacklist': HostFilter.blacklist.toJson(),
+ };
+ }
+}
diff --git a/lib/network/bin/server.dart b/lib/network/bin/server.dart
index b6585da..3e4ffef 100644
--- a/lib/network/bin/server.dart
+++ b/lib/network/bin/server.dart
@@ -1,82 +1,39 @@
import 'dart:async';
-import 'dart:convert';
import 'dart:io';
-import 'package:network_proxy/network/util/host_filter.dart';
-import 'package:network_proxy/utils/platform.dart';
-import 'package:path_provider/path_provider.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import '../channel.dart';
import '../handler.dart';
import '../http/codec.dart';
import '../util/logger.dart';
-import '../util/request_rewrite.dart';
import '../util/system_proxy.dart';
Future main() async {
- ProxyServer().start();
+ var configuration = await Configuration.instance;
+ ProxyServer(configuration).start();
}
/// 代理服务器
class ProxyServer {
- //是否初始化
- bool init = false;
- int port = 9099;
-
- //是否启用https抓包
- bool _enableSsl = false;
-
- //是否启用桌面抓包
- bool enableDesktop = true;
-
- //是否引导
- bool guide = false;
-
//是否启动
bool get isRunning => server?.isRunning ?? false;
-
Server? server;
//请求事件监听
EventListener? listener;
- //请求重写
- RequestRewrites requestRewrites = RequestRewrites();
+ final Configuration configuration;
- final List _initializedListeners = [];
-
- ProxyServer({this.listener});
-
- //初始化
- Future initializedListener(Function action) async {
- _initializedListeners.add(action);
- }
-
- Future homeDir() async {
- String? userHome;
- if (Platforms.isDesktop()) {
- userHome =
- Platform.environment['HOME'] ?? Platform.environment['USERPROFILE'];
- } else {
- userHome = (await getApplicationSupportDirectory()).path;
- }
-
- var separator = Platform.pathSeparator;
- return File("${userHome!}$separator.proxypin");
- }
-
- /// 配置文件
- Future configFile() async {
- var separator = Platform.pathSeparator;
- var home = await homeDir();
- return File("${home.path}${separator}config.cnf");
- }
+ ProxyServer(this.configuration, {this.listener});
///是否启用https抓包
- bool get enableSsl => _enableSsl;
+ bool get enableSsl => configuration.enableSsl;
+
+ int get port => configuration.port;
set enableSsl(bool enableSsl) {
- _enableSsl = enableSsl;
+ configuration.enableSsl = enableSsl;
server?.enableSsl = enableSsl;
if (server == null || server?.isRunning == false) {
return;
@@ -90,27 +47,16 @@ class ProxyServer {
/// 启动代理服务
Future start() async {
Server server = Server();
- if (!init) {
- // 读取配置文件
- init = true;
- await _loadConfig();
- for (var element in _initializedListeners) {
- element.call();
- }
- }
- server.enableSsl = _enableSsl;
+ server.enableSsl = configuration.enableSsl;
server.initChannel((channel) {
- channel.pipeline.handle(
- HttpRequestCodec(),
- HttpResponseCodec(),
- HttpChannelHandler(
- listener: listener, requestRewrites: requestRewrites));
+ channel.pipeline.handle(HttpRequestCodec(), HttpResponseCodec(),
+ HttpChannelHandler(listener: listener, requestRewrites: configuration.requestRewrites));
});
return server.bind(port).then((serverSocket) {
logger.i("listen on $port");
this.server = server;
- if (enableDesktop) {
+ if (configuration.enableDesktop) {
SystemProxy.setSystemProxy(port, enableSsl);
}
return server;
@@ -120,7 +66,7 @@ class ProxyServer {
/// 停止代理服务
Future stop() async {
logger.i("stop on $port");
- if (enableDesktop) {
+ if (configuration.enableDesktop) {
if (Platform.isMacOS) {
await SystemProxy.setProxyEnableMacOS(false, enableSsl);
} else if (Platform.isWindows) {
@@ -135,80 +81,4 @@ class ProxyServer {
restart() {
stop().then((value) => start());
}
-
- /// 刷新配置文件
- flushConfig() async {
- var file = await configFile();
- var exists = await file.exists();
- if (!exists) {
- file = await file.create(recursive: true);
- }
- HostFilter.whitelist.toJson();
- HostFilter.blacklist.toJson();
- var json = jsonEncode(toJson());
- logger.i('刷新配置文件 $runtimeType ${toJson()}');
- file.writeAsString(json);
- }
-
- /// 加载配置文件
- Future _loadConfig() async {
- var file = await configFile();
- var exits = await file.exists();
- if (!exits) {
- guide = true;
- return;
- }
-
- Map config = jsonDecode(await file.readAsString());
- logger.i('加载配置文件 [$file]');
- port = config['port'] ?? port;
- enableSsl = config['enableSsl'] == true;
- enableDesktop = config['enableDesktop'] ?? true;
- guide = config['guide'] ?? false;
- HostFilter.whitelist.load(config['whitelist']);
- HostFilter.blacklist.load(config['blacklist']);
-
- await _loadRequestRewriteConfig();
- }
-
- /// 加载请求重写配置文件
- Future _loadRequestRewriteConfig() async {
- var home = await homeDir();
- var file =
- File('${home.path}${Platform.pathSeparator}request_rewrite.json');
- var exits = await file.exists();
- if (!exits) {
- return;
- }
-
- Map config = jsonDecode(await file.readAsString());
-
- logger.i('加载请求重写配置文件 [$file]');
- requestRewrites.load(config);
- }
-
- /// 保存请求重写配置文件
- flushRequestRewriteConfig() async {
- var home = await homeDir();
- var file =
- File('${home.path}${Platform.pathSeparator}request_rewrite.json');
- bool exists = await file.exists();
- if (!exists) {
- await file.create(recursive: true);
- }
- var json = jsonEncode(requestRewrites.toJson());
- logger.i('刷新请求重写配置文件 ${file.path}');
- file.writeAsString(json);
- }
-
- Map toJson() {
- return {
- 'guide': guide,
- 'port': port,
- 'enableSsl': enableSsl,
- 'enableDesktop': enableDesktop,
- 'whitelist': HostFilter.whitelist.toJson(),
- 'blacklist': HostFilter.blacklist.toJson(),
- };
- }
}
diff --git a/lib/ui/content/body.dart b/lib/ui/content/body.dart
index d9aca40..9c45a2a 100644
--- a/lib/ui/content/body.dart
+++ b/lib/ui/content/body.dart
@@ -125,7 +125,7 @@ class HttpBodyState extends State {
var size = MediaQuery.of(context).size;
var ratio = 1.0;
if (Platform.isWindows) {
- WindowManager.instance.getDevicePixelRatio();
+ ratio = WindowManager.instance.getDevicePixelRatio();
}
final window = await DesktopMultiWindow.createWindow(jsonEncode(
{'name': 'HttpBodyWidget', 'httpMessage': widget.httpMessage, 'inNewWindow': true},
diff --git a/lib/ui/desktop/left/domain.dart b/lib/ui/desktop/left/domain.dart
index 7efd5e4..b44d342 100644
--- a/lib/ui/desktop/left/domain.dart
+++ b/lib/ui/desktop/left/domain.dart
@@ -2,6 +2,7 @@ import 'dart:collection';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/channel.dart';
import 'package:network_proxy/network/http/http.dart';
@@ -154,7 +155,15 @@ class HeaderBody extends StatefulWidget {
///根据文本过滤
Iterable filter(String text) {
- return _body.where((element) => element.request.requestUrl.toLowerCase().contains(text));
+ return _body.where((element) {
+ if (element.request.method.name.toLowerCase() == text) {
+ return true;
+ }
+ if (element.request.requestUrl.toLowerCase().contains(text)) {
+ return true;
+ }
+ return element.response.get()?.contentType.name.toLowerCase().contains(text) == true;
+ });
}
///复制
@@ -175,12 +184,13 @@ class HeaderBody extends StatefulWidget {
class _HeaderBodyState extends State {
final GlobalKey transitionState = GlobalKey();
-
+ late Configuration configuration;
late bool selected;
@override
void initState() {
super.initState();
+ configuration = widget.proxyServer.configuration;
selected = widget.selected;
}
@@ -241,21 +251,21 @@ class _HeaderBodyState extends State {
child: const Text("添加黑名单", style: TextStyle(fontSize: 14)),
onTap: () {
HostFilter.blacklist.add(widget.header.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
}),
PopupMenuItem(
height: 38,
child: const Text("添加白名单", style: TextStyle(fontSize: 14)),
onTap: () {
HostFilter.whitelist.add(widget.header.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
}),
PopupMenuItem(
height: 38,
child: const Text("删除白名单", style: TextStyle(fontSize: 14)),
onTap: () {
HostFilter.whitelist.remove(widget.header.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
}),
PopupMenuItem(height: 38, child: const Text("删除", style: TextStyle(fontSize: 14)), onTap: () => _delete()),
],
diff --git a/lib/ui/desktop/left/path.dart b/lib/ui/desktop/left/path.dart
index 4b55ae1..c744628 100644
--- a/lib/ui/desktop/left/path.dart
+++ b/lib/ui/desktop/left/path.dart
@@ -131,7 +131,7 @@ class _PathRowState extends State {
var size = MediaQuery.of(context).size;
var ratio = 1.0;
if (Platform.isWindows) {
- WindowManager.instance.getDevicePixelRatio();
+ ratio = WindowManager.instance.getDevicePixelRatio();
}
final window = await DesktopMultiWindow.createWindow(jsonEncode(
diff --git a/lib/ui/desktop/toolbar/setting/filter.dart b/lib/ui/desktop/toolbar/setting/filter.dart
index cdb2dd8..c067043 100644
--- a/lib/ui/desktop/toolbar/setting/filter.dart
+++ b/lib/ui/desktop/toolbar/setting/filter.dart
@@ -1,12 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:network_proxy/network/bin/server.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/util/host_filter.dart';
-
class FilterDialog extends StatefulWidget {
- final ProxyServer proxyServer;
+ final Configuration configuration;
- const FilterDialog({super.key, required this.proxyServer});
+ const FilterDialog({super.key, required this.configuration});
@override
State createState() => _FilterDialogState();
@@ -49,7 +48,7 @@ class _FilterDialogState extends State {
title: "白名单",
subtitle: "只代理白名单中的域名, 白名单启用黑名单将会失效",
hostList: HostFilter.whitelist,
- proxyServer: widget.proxyServer,
+ configuration: widget.configuration,
hostEnableNotifier: hostEnableNotifier)),
const SizedBox(width: 10),
Expanded(
@@ -58,7 +57,7 @@ class _FilterDialogState extends State {
title: "黑名单",
subtitle: "黑名单中的域名不会代理",
hostList: HostFilter.blacklist,
- proxyServer: widget.proxyServer,
+ configuration: widget.configuration,
hostEnableNotifier: hostEnableNotifier)),
],
),
@@ -70,7 +69,7 @@ class DomainFilter extends StatefulWidget {
final String title;
final String subtitle;
final HostList hostList;
- final ProxyServer proxyServer;
+ final Configuration configuration;
final ValueNotifier hostEnableNotifier;
const DomainFilter(
@@ -79,7 +78,7 @@ class DomainFilter extends StatefulWidget {
required this.subtitle,
required this.hostList,
required this.hostEnableNotifier,
- required this.proxyServer});
+ required this.configuration});
@override
State createState() {
@@ -145,7 +144,7 @@ class _DomainFilterState extends State {
@override
void dispose() {
if (changed) {
- widget.proxyServer.flushConfig();
+ widget.configuration.flushConfig();
}
super.dispose();
}
diff --git a/lib/ui/desktop/toolbar/setting/request_rewrite.dart b/lib/ui/desktop/toolbar/setting/request_rewrite.dart
index 3f128b5..a491a10 100644
--- a/lib/ui/desktop/toolbar/setting/request_rewrite.dart
+++ b/lib/ui/desktop/toolbar/setting/request_rewrite.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:network_proxy/network/bin/server.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/util/request_rewrite.dart';
class RequestRewrite extends StatefulWidget {
- final ProxyServer proxyServer;
+ final Configuration configuration;
- const RequestRewrite({super.key, required this.proxyServer});
+ const RequestRewrite({super.key, required this.configuration});
@override
State createState() => _RequestRewriteState();
@@ -19,15 +19,15 @@ class _RequestRewriteState extends State {
@override
void initState() {
super.initState();
- requestRuleList = RequestRuleList(widget.proxyServer.requestRewrites);
- enableNotifier = ValueNotifier(widget.proxyServer.requestRewrites.enabled == true);
+ requestRuleList = RequestRuleList(widget.configuration.requestRewrites);
+ enableNotifier = ValueNotifier(widget.configuration.requestRewrites.enabled == true);
}
@override
void dispose() {
- if (changed || enableNotifier.value != widget.proxyServer.requestRewrites.enabled) {
- widget.proxyServer.requestRewrites.enabled = enableNotifier.value;
- widget.proxyServer.flushRequestRewriteConfig();
+ if (changed || enableNotifier.value != widget.configuration.requestRewrites.enabled) {
+ widget.configuration.requestRewrites.enabled = enableNotifier.value;
+ widget.configuration.flushRequestRewriteConfig();
}
enableNotifier.dispose();
@@ -80,7 +80,7 @@ class _RequestRewriteState extends State {
changed = true;
setState(() {
- widget.proxyServer.requestRewrites.removeIndex(removeSelected);
+ widget.configuration.requestRewrites.removeIndex(removeSelected);
requestRuleList.changeState();
});
})
@@ -97,7 +97,7 @@ class _RequestRewriteState extends State {
barrierDismissible: false,
builder: (BuildContext context) {
return RuleAddDialog(
- requestRewrites: widget.proxyServer.requestRewrites,
+ requestRewrites: widget.configuration.requestRewrites,
currentIndex: currentIndex,
onChange: () {
changed = true;
@@ -250,7 +250,7 @@ class _RequestRuleListState extends State {
border: TableBorder.symmetric(outside: BorderSide(width: 1, color: Theme.of(context).highlightColor)),
columns: const [
DataColumn(label: Text('启用')),
- DataColumn(label: Text('URL')),
+ DataColumn(label: Text('Path')),
DataColumn(label: Text('请求体')),
DataColumn(label: Text('响应体')),
],
diff --git a/lib/ui/desktop/toolbar/setting/setting.dart b/lib/ui/desktop/toolbar/setting/setting.dart
index 06248d3..a809b80 100644
--- a/lib/ui/desktop/toolbar/setting/setting.dart
+++ b/lib/ui/desktop/toolbar/setting/setting.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/util/system_proxy.dart';
import 'package:network_proxy/ui/desktop/toolbar/setting/request_rewrite.dart';
@@ -20,10 +21,12 @@ class Setting extends StatefulWidget {
class _SettingState extends State {
late ValueNotifier enableDesktopListenable;
+ late Configuration configuration;
@override
void initState() {
- enableDesktopListenable = ValueNotifier(widget.proxyServer.enableDesktop);
+ configuration = widget.proxyServer.configuration;
+ enableDesktopListenable = ValueNotifier(configuration.enableDesktop);
super.initState();
}
@@ -54,12 +57,12 @@ class _SettingState extends State {
title: const Text("抓取电脑请求"),
visualDensity: const VisualDensity(horizontal: -4),
dense: true,
- value: widget.proxyServer.enableDesktop,
+ value: configuration.enableDesktop,
onChanged: (val) {
SystemProxy.setSystemProxyEnable(widget.proxyServer.port, val, widget.proxyServer.enableSsl);
- widget.proxyServer.enableDesktop = val;
+ configuration.enableDesktop = val;
enableDesktopListenable.value = !enableDesktopListenable.value;
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
}))),
const PopupMenuItem(padding: EdgeInsets.all(0), child: ThemeSetting(dense: true)),
menuItem("域名过滤", onTap: () => hostFilter()),
@@ -106,7 +109,7 @@ class _SettingState extends State {
label: const Text("关闭"),
onPressed: () => Navigator.of(context).pop())))
]),
- content: RequestRewrite(proxyServer: widget.proxyServer),
+ content: RequestRewrite(configuration: configuration),
);
});
}
@@ -117,7 +120,7 @@ class _SettingState extends State {
barrierDismissible: false,
context: context,
builder: (context) {
- return FilterDialog(proxyServer: widget.proxyServer);
+ return FilterDialog(configuration: configuration);
},
);
}
@@ -146,11 +149,11 @@ class _PortState extends State {
portFocus.addListener(() async {
//失去焦点
if (!portFocus.hasFocus && textController.text != widget.proxyServer.port.toString()) {
- widget.proxyServer.port = int.parse(textController.text);
+ widget.proxyServer.configuration.port = int.parse(textController.text);
if (widget.proxyServer.isRunning) {
widget.proxyServer.restart();
}
- widget.proxyServer.flushConfig();
+ widget.proxyServer.configuration.flushConfig();
}
});
}
diff --git a/lib/ui/desktop/toolbar/ssl/ssl.dart b/lib/ui/desktop/toolbar/ssl/ssl.dart
index 4b78d83..45a3c8f 100644
--- a/lib/ui/desktop/toolbar/ssl/ssl.dart
+++ b/lib/ui/desktop/toolbar/ssl/ssl.dart
@@ -19,22 +19,10 @@ class SslWidget extends StatefulWidget {
}
class _SslState extends State {
- bool _enableSsl = true;
-
- @override
- void initState() {
- super.initState();
-
- widget.proxyServer.initializedListener(() {
- _enableSsl = widget.proxyServer.enableSsl;
- setState(() {});
- });
- }
-
@override
Widget build(BuildContext context) {
return PopupMenuButton(
- icon: Icon(Icons.https, color: _enableSsl ? null : Colors.red),
+ icon: Icon(Icons.https, color: widget.proxyServer.enableSsl ? null : Colors.red),
surfaceTintColor: Colors.white70,
tooltip: "HTTPS代理",
offset: const Offset(10, 30),
@@ -42,11 +30,7 @@ class _SslState extends State {
return [
PopupMenuItem(
padding: const EdgeInsets.all(0),
- child: _Switch(
- proxyServer: widget.proxyServer,
- onEnableChange: (val) => setState(() {
- _enableSsl = val;
- }))),
+ child: _Switch(proxyServer: widget.proxyServer, onEnableChange: (val) => setState(() {}))),
PopupMenuItem(
padding: const EdgeInsets.all(0),
child: ListTile(
@@ -282,7 +266,7 @@ class _SwitchState extends State<_Switch> {
void dispose() {
super.dispose();
if (changed) {
- widget.proxyServer.flushConfig();
+ widget.proxyServer.configuration.flushConfig();
}
}
}
diff --git a/lib/ui/launch/launch.dart b/lib/ui/launch/launch.dart
index a5c47c9..aa8623f 100644
--- a/lib/ui/launch/launch.dart
+++ b/lib/ui/launch/launch.dart
@@ -1,16 +1,17 @@
import 'package:flutter/material.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:network_proxy/network/bin/server.dart';
-import 'package:network_proxy/network/channel.dart';
import 'package:window_manager/window_manager.dart';
class SocketLaunch extends StatefulWidget {
final ProxyServer proxyServer;
final int size;
+ final bool startup;
final Function? onStart;
final Function? onStop;
- const SocketLaunch({super.key, required this.proxyServer, this.size = 25, this.onStart, this.onStop});
+ const SocketLaunch(
+ {super.key, required this.proxyServer, this.size = 25, this.onStart, this.onStop, this.startup = true});
@override
State createState() {
@@ -27,14 +28,9 @@ class _SocketLaunchState extends State with WindowListener, Widget
windowManager.addListener(this);
WidgetsBinding.instance.addObserver(this);
//启动代理服务器
- widget.proxyServer.start().then((value) {
- setState(() {
- started = true;
- });
- widget.onStart?.call();
- }).catchError((e) {
- FlutterToastr.show("启动失败,请检查端口号${widget.proxyServer.port}是否被占用", context, duration: 3);
- });
+ if (widget.startup) {
+ start();
+ }
}
@override
@@ -70,19 +66,27 @@ class _SocketLaunchState extends State with WindowListener, Widget
icon: Icon(started ? Icons.stop : Icons.play_arrow_sharp,
color: started ? Colors.red : Colors.green, size: widget.size.toDouble()),
onPressed: () async {
- Future result = started ? widget.proxyServer.stop() : widget.proxyServer.start();
if (started) {
- widget.onStop?.call();
+ widget.proxyServer.stop().then((value) {
+ widget.onStop?.call();
+ setState(() {
+ started = !started;
+ });
+ });
} else {
- widget.onStart?.call();
+ start();
}
- result
- .then((value) => setState(() {
- started = !started;
- }))
- .catchError((e) {
- FlutterToastr.show("启动失败,请检查端口号${widget.proxyServer.port}是否被占用", context);
- });
});
}
+
+ start() {
+ widget.proxyServer.start().then((value) {
+ setState(() {
+ started = true;
+ });
+ widget.onStart?.call();
+ }).catchError((e) {
+ FlutterToastr.show("启动失败,请检查端口号${widget.proxyServer.port}是否被占用", context, duration: 3);
+ });
+ }
}
diff --git a/lib/ui/mobile/connect_remote.dart b/lib/ui/mobile/connect_remote.dart
index f353b3c..074c619 100644
--- a/lib/ui/mobile/connect_remote.dart
+++ b/lib/ui/mobile/connect_remote.dart
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:flutter/material.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/http_client.dart';
import 'package:network_proxy/network/util/host_filter.dart';
@@ -75,7 +76,7 @@ class ConnectRemoteState extends State {
showDialog(
context: context,
builder: (context) {
- return ConfigSyncWidget(proxyServer: widget.proxyServer, config: config);
+ return ConfigSyncWidget(configuration: widget.proxyServer.configuration, config: config);
});
}
}).onError((error, stackTrace) {
@@ -86,10 +87,10 @@ class ConnectRemoteState extends State {
}
class ConfigSyncWidget extends StatefulWidget {
- final ProxyServer proxyServer;
+ final Configuration configuration;
final Map config;
- const ConfigSyncWidget({super.key, required this.proxyServer, required this.config});
+ const ConfigSyncWidget({super.key, required this.configuration, required this.config});
@override
State createState() {
@@ -152,10 +153,10 @@ class ConfigSyncState extends State {
HostFilter.blacklist.load(widget.config['blacklist']);
}
if (syncRewrite) {
- widget.proxyServer.requestRewrites.load(widget.config['requestRewrites']);
- widget.proxyServer.flushRequestRewriteConfig();
+ widget.configuration.requestRewrites.load(widget.config['requestRewrites']);
+ widget.configuration.flushRequestRewriteConfig();
}
- widget.proxyServer.flushConfig();
+ widget.configuration.flushConfig();
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('同步成功')));
}),
diff --git a/lib/ui/mobile/menu.dart b/lib/ui/mobile/menu.dart
index 013181a..4d91674 100644
--- a/lib/ui/mobile/menu.dart
+++ b/lib/ui/mobile/menu.dart
@@ -43,17 +43,17 @@ class DrawerWidget extends StatelessWidget {
ListTile(
title: const Text("域名白名单"),
trailing: const Icon(Icons.arrow_right),
- onTap: () =>
- navigator(context, MobileFilterWidget(proxyServer: proxyServer, hostList: HostFilter.whitelist))),
+ onTap: () => navigator(
+ context, MobileFilterWidget(configuration: proxyServer.configuration, hostList: HostFilter.whitelist))),
ListTile(
title: const Text("域名黑名单"),
trailing: const Icon(Icons.arrow_right),
- onTap: () =>
- navigator(context, MobileFilterWidget(proxyServer: proxyServer, hostList: HostFilter.blacklist))),
+ onTap: () => navigator(
+ context, MobileFilterWidget(configuration: proxyServer.configuration, hostList: HostFilter.blacklist))),
ListTile(
title: const Text("请求重写"),
trailing: const Icon(Icons.arrow_right),
- onTap: () => navigator(context, MobileRequestRewrite(proxyServer: proxyServer))),
+ onTap: () => navigator(context, MobileRequestRewrite(configuration: proxyServer.configuration))),
ListTile(
title: const Text("Github"),
trailing: const Icon(Icons.arrow_right),
@@ -169,7 +169,7 @@ class MoreEnum extends StatelessWidget {
hostname: response.headers.get("hostname"));
if (context.mounted && Navigator.canPop(context)) {
- FlutterToastr.show("连接成功", context);
+ FlutterToastr.show("连接成功${proxyServer.isRunning ? '' : ',手机需要开启抓包才可以抓取请求哦'}", context);
Navigator.pop(context);
}
}
diff --git a/lib/ui/mobile/mobile.dart b/lib/ui/mobile/mobile.dart
index 48d2404..b6ec3db 100644
--- a/lib/ui/mobile/mobile.dart
+++ b/lib/ui/mobile/mobile.dart
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:network_proxy/native/vpn.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/channel.dart';
import 'package:network_proxy/network/handler.dart';
@@ -13,7 +14,9 @@ import 'package:network_proxy/ui/mobile/menu.dart';
import 'package:network_proxy/ui/mobile/request/list.dart';
class MobileHomePage extends StatefulWidget {
- const MobileHomePage({super.key});
+ final Configuration configuration;
+
+ const MobileHomePage({super.key, required this.configuration});
@override
State createState() {
@@ -39,7 +42,7 @@ class MobileHomeState extends State implements EventListener {
@override
void initState() {
- proxyServer = ProxyServer(listener: this);
+ proxyServer = ProxyServer(widget.configuration, listener: this);
desktop.addListener(() {
if (desktop.value.connect) {
proxyServer.server?.remoteHost = "http://${desktop.value.host}:${desktop.value.port}";
@@ -48,7 +51,26 @@ class MobileHomeState extends State implements EventListener {
proxyServer.server?.remoteHost = null;
}
});
+
super.initState();
+
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ if (widget.configuration.guide) {
+ //首次引导
+ String content = '默认不会开启HTTPS抓包,请安装证书后再开启HTTPS抓包。\n'
+ '点击的设置 -> HTTPS抓包,根据提示安装证书操作即可。';
+ showAlertDialog('提示', content, () {
+ widget.configuration.guide = false;
+ widget.configuration.upgradeNotice = false;
+ widget.configuration.flushConfig();
+ });
+ return;
+ }
+
+ if (widget.configuration.upgradeNotice) {
+ showUpgradeNotice();
+ }
+ });
}
@override
@@ -74,6 +96,7 @@ class MobileHomeState extends State implements EventListener {
onPressed: () {},
child: SocketLaunch(
proxyServer: proxyServer,
+ startup: false,
size: 38,
onStart: () => Vpn.startVpn("127.0.0.1", proxyServer.port),
onStop: () => Vpn.stopVpn())),
@@ -100,6 +123,32 @@ class MobileHomeState extends State implements EventListener {
);
}
+ showUpgradeNotice() {
+ String content = '1. 手机版启动默认不再自动开启抓包,请手动点击启动按钮。\n'
+ '2. 增加外部代理,可配置其他VPN软件地址,开启抓包不会影响访问外网。\n'
+ '3. 搜索功能增强,可直接搜索响应类型和请求方法。';
+ showAlertDialog('更新内容', content, () {
+ widget.configuration.upgradeNotice = false;
+ widget.configuration.flushConfig();
+ });
+ }
+
+ showAlertDialog(String title, String content, Function onClose) {
+ showDialog(
+ context: context,
+ barrierDismissible: false,
+ builder: (_) {
+ return AlertDialog(actions: [
+ TextButton(
+ onPressed: () {
+ onClose.call();
+ Navigator.pop(context);
+ },
+ child: const Text('关闭'))
+ ], title: Text(title, style: const TextStyle(fontSize: 18)), content: Text(content));
+ });
+ }
+
/// 搜索框
Widget search() {
return Padding(
diff --git a/lib/ui/mobile/request/list.dart b/lib/ui/mobile/request/list.dart
index 65a52ae..1cf131b 100644
--- a/lib/ui/mobile/request/list.dart
+++ b/lib/ui/mobile/request/list.dart
@@ -3,6 +3,7 @@ import 'dart:collection';
import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/channel.dart';
import 'package:network_proxy/network/http/http.dart';
@@ -160,17 +161,26 @@ class RequestSequenceState extends State with AutomaticKeepAliv
}
bool filter(HttpRequest request) {
- if (searchText?.isNotEmpty == true) {
- return request.requestUrl.toLowerCase().contains(searchText!);
+ if (searchText == null || searchText!.isEmpty) {
+ return true;
}
- return true;
+
+ if (request.method.name.toLowerCase() == searchText) {
+ return true;
+ }
+
+ if (request.requestUrl.toLowerCase().contains(searchText!)) {
+ return true;
+ }
+
+ return request.response?.contentType.name.toLowerCase().contains(searchText!) == true;
}
changeState() {
//防止频繁刷新
if (!changing) {
changing = true;
- Future.delayed(const Duration(milliseconds: 300), () {
+ Future.delayed(const Duration(milliseconds: 100), () {
setState(() {
changing = false;
});
@@ -217,6 +227,7 @@ class DomainList extends StatefulWidget {
class DomainListState extends State with AutomaticKeepAliveClientMixin {
GlobalKey requestSequenceKey = GlobalKey();
+ late Configuration configuration;
//域名和对应请求列表的映射
Map> containerMap = {};
@@ -235,6 +246,8 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
@override
initState() {
super.initState();
+ configuration = widget.proxyServer.configuration;
+
for (var request in widget.list) {
var hostAndPort = request.hostAndPort!;
container.add(hostAndPort);
@@ -271,7 +284,7 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
//防止频繁刷新
if (!changing) {
changing = true;
- Future.delayed(const Duration(milliseconds: 200), () {
+ Future.delayed(const Duration(milliseconds: 50), () {
setState(() {
changing = false;
});
@@ -332,7 +345,7 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
var time =
formatDate(containerMap[list.elementAt(index)]!.last.requestTime, [m, '/', d, ' ', HH, ':', nn, ':', ss]);
return ListTile(
- visualDensity: const VisualDensity( vertical: -4),
+ visualDensity: const VisualDensity(vertical: -4),
title: Text(list.elementAt(index).domain, maxLines: 1, overflow: TextOverflow.ellipsis),
trailing: const Icon(Icons.chevron_right),
subtitle: Text("最后请求时间: $time, 次数: ${containerMap[list.elementAt(index)]!.length}",
@@ -366,7 +379,7 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
child: const SizedBox(width: double.infinity, child: Text("添加黑名单", textAlign: TextAlign.center)),
onPressed: () {
HostFilter.blacklist.add(hostAndPort.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
FlutterToastr.show("已添加至黑名单", context);
Navigator.of(context).pop();
}),
@@ -375,7 +388,7 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
child: const SizedBox(width: double.infinity, child: Text("添加白名单", textAlign: TextAlign.center)),
onPressed: () {
HostFilter.whitelist.add(hostAndPort.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
FlutterToastr.show("已添加至白名单", context);
Navigator.of(context).pop();
}),
@@ -384,7 +397,7 @@ class DomainListState extends State with AutomaticKeepAliveClientMix
child: const SizedBox(width: double.infinity, child: Text("删除白名单", textAlign: TextAlign.center)),
onPressed: () {
HostFilter.whitelist.remove(hostAndPort.host);
- widget.proxyServer.flushConfig();
+ configuration.flushConfig();
FlutterToastr.show("已删除白名单", context);
Navigator.of(context).pop();
}),
diff --git a/lib/ui/mobile/setting/filter.dart b/lib/ui/mobile/setting/filter.dart
index 6ef6a0d..52a57c3 100644
--- a/lib/ui/mobile/setting/filter.dart
+++ b/lib/ui/mobile/setting/filter.dart
@@ -1,13 +1,13 @@
import 'package:flutter/material.dart';
-import 'package:network_proxy/network/bin/server.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import '../../../../network/util/host_filter.dart';
class MobileFilterWidget extends StatefulWidget {
- final ProxyServer proxyServer;
+ final Configuration configuration;
final HostList hostList;
- const MobileFilterWidget({super.key, required this.proxyServer, required this.hostList});
+ const MobileFilterWidget({super.key, required this.configuration, required this.hostList});
@override
State createState() => _MobileFilterState();
@@ -34,7 +34,7 @@ class _MobileFilterState extends State {
title: title,
subtitle: subtitle,
hostList: widget.hostList,
- proxyServer: widget.proxyServer,
+ configuration: widget.configuration,
hostEnableNotifier: hostEnableNotifier),
));
}
@@ -44,7 +44,7 @@ class DomainFilter extends StatefulWidget {
final String title;
final String subtitle;
final HostList hostList;
- final ProxyServer proxyServer;
+ final Configuration configuration;
final ValueNotifier hostEnableNotifier;
const DomainFilter(
@@ -53,7 +53,7 @@ class DomainFilter extends StatefulWidget {
required this.subtitle,
required this.hostList,
required this.hostEnableNotifier,
- required this.proxyServer});
+ required this.configuration});
@override
State createState() {
@@ -114,7 +114,7 @@ class _DomainFilterState extends State {
@override
void dispose() {
if (changed) {
- widget.proxyServer.flushConfig();
+ widget.configuration.flushConfig();
}
super.dispose();
}
diff --git a/lib/ui/mobile/setting/request_rewrite.dart b/lib/ui/mobile/setting/request_rewrite.dart
index 0983d84..f1b3f56 100644
--- a/lib/ui/mobile/setting/request_rewrite.dart
+++ b/lib/ui/mobile/setting/request_rewrite.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:network_proxy/network/bin/server.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/util/request_rewrite.dart';
class MobileRequestRewrite extends StatefulWidget {
- final ProxyServer proxyServer;
+ final Configuration configuration;
- const MobileRequestRewrite({super.key, required this.proxyServer});
+ const MobileRequestRewrite({super.key, required this.configuration});
@override
State createState() => _MobileRequestRewriteState();
@@ -19,15 +19,15 @@ class _MobileRequestRewriteState extends State {
@override
void initState() {
super.initState();
- requestRuleList = RequestRuleList(widget.proxyServer.requestRewrites);
- enableNotifier = ValueNotifier(widget.proxyServer.requestRewrites.enabled);
+ requestRuleList = RequestRuleList(widget.configuration.requestRewrites);
+ enableNotifier = ValueNotifier(widget.configuration.requestRewrites.enabled);
}
@override
void dispose() {
- if (changed || enableNotifier.value != widget.proxyServer.requestRewrites.enabled) {
- widget.proxyServer.requestRewrites.enabled = enableNotifier.value;
- widget.proxyServer.flushRequestRewriteConfig();
+ if (changed || enableNotifier.value != widget.configuration.requestRewrites.enabled) {
+ widget.configuration.requestRewrites.enabled = enableNotifier.value;
+ widget.configuration.flushRequestRewriteConfig();
}
enableNotifier.dispose();
@@ -81,7 +81,7 @@ class _MobileRequestRewriteState extends State {
changed = true;
setState(() {
- widget.proxyServer.requestRewrites.removeIndex(removeSelected);
+ widget.configuration.requestRewrites.removeIndex(removeSelected);
requestRuleList.changeState();
});
})
@@ -97,7 +97,7 @@ class _MobileRequestRewriteState extends State {
context: context,
builder: (BuildContext context) {
return RuleAddDialog(
- requestRewrites: widget.proxyServer.requestRewrites,
+ requestRewrites: widget.configuration.requestRewrites,
currentIndex: currentIndex,
onChange: () {
changed = true;
@@ -248,7 +248,7 @@ class _RequestRuleListState extends State {
border: TableBorder.symmetric(outside: BorderSide(width: 1, color: Theme.of(context).highlightColor)),
columns: const [
DataColumn(label: Text('启用')),
- DataColumn(label: Text('URL')),
+ DataColumn(label: Text('Path')),
DataColumn(label: Text('请求体')),
DataColumn(label: Text('响应体')),
],
diff --git a/lib/ui/mobile/setting/ssl.dart b/lib/ui/mobile/setting/ssl.dart
index 956097d..ed18325 100644
--- a/lib/ui/mobile/setting/ssl.dart
+++ b/lib/ui/mobile/setting/ssl.dart
@@ -21,7 +21,7 @@ class _MobileSslState extends State {
@override
void dispose() {
if (changed) {
- widget.proxyServer.flushConfig();
+ widget.proxyServer.configuration.flushConfig();
}
super.dispose();
}
diff --git a/test/widget_test.dart b/test/widget_test.dart
index 9da8e48..e112485 100644
--- a/test/widget_test.dart
+++ b/test/widget_test.dart
@@ -9,11 +9,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:network_proxy/main.dart';
+import 'package:network_proxy/network/bin/configuration.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
- await tester.pumpWidget(const FluentApp(DesktopHomePage()));
+ Configuration configuration = await Configuration.instance;
+ await tester.pumpWidget(FluentApp(DesktopHomePage(configuration: configuration)));
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);