手机版启动默认不再自动开启抓包

This commit is contained in:
wanghongen
2023-07-30 01:07:23 +08:00
parent b13cd10de1
commit 8a466dc11a
24 changed files with 416 additions and 295 deletions

View File

@@ -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<ConnectRemote> {
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<ConnectRemote> {
}
class ConfigSyncWidget extends StatefulWidget {
final ProxyServer proxyServer;
final Configuration configuration;
final Map<String, dynamic> config;
const ConfigSyncWidget({super.key, required this.proxyServer, required this.config});
const ConfigSyncWidget({super.key, required this.configuration, required this.config});
@override
State<StatefulWidget> createState() {
@@ -152,10 +153,10 @@ class ConfigSyncState extends State<ConfigSyncWidget> {
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('同步成功')));
}),

View File

@@ -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);
}
}

View File

@@ -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<StatefulWidget> createState() {
@@ -39,7 +42,7 @@ class MobileHomeState extends State<MobileHomePage> 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<MobileHomePage> 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<MobileHomePage> 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<MobileHomePage> 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(

View File

@@ -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<RequestSequence> 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<DomainList> with AutomaticKeepAliveClientMixin {
GlobalKey<RequestSequenceState> requestSequenceKey = GlobalKey<RequestSequenceState>();
late Configuration configuration;
//域名和对应请求列表的映射
Map<HostAndPort, List<HttpRequest>> containerMap = {};
@@ -235,6 +246,8 @@ class DomainListState extends State<DomainList> 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<DomainList> 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<DomainList> 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<DomainList> 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<DomainList> 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<DomainList> 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();
}),

View File

@@ -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<MobileFilterWidget> createState() => _MobileFilterState();
@@ -34,7 +34,7 @@ class _MobileFilterState extends State<MobileFilterWidget> {
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<bool> 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<StatefulWidget> createState() {
@@ -114,7 +114,7 @@ class _DomainFilterState extends State<DomainFilter> {
@override
void dispose() {
if (changed) {
widget.proxyServer.flushConfig();
widget.configuration.flushConfig();
}
super.dispose();
}

View File

@@ -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<MobileRequestRewrite> createState() => _MobileRequestRewriteState();
@@ -19,15 +19,15 @@ class _MobileRequestRewriteState extends State<MobileRequestRewrite> {
@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<MobileRequestRewrite> {
changed = true;
setState(() {
widget.proxyServer.requestRewrites.removeIndex(removeSelected);
widget.configuration.requestRewrites.removeIndex(removeSelected);
requestRuleList.changeState();
});
})
@@ -97,7 +97,7 @@ class _MobileRequestRewriteState extends State<MobileRequestRewrite> {
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<RequestRuleList> {
border: TableBorder.symmetric(outside: BorderSide(width: 1, color: Theme.of(context).highlightColor)),
columns: const <DataColumn>[
DataColumn(label: Text('启用')),
DataColumn(label: Text('URL')),
DataColumn(label: Text('Path')),
DataColumn(label: Text('请求体')),
DataColumn(label: Text('响应体')),
],

View File

@@ -21,7 +21,7 @@ class _MobileSslState extends State<MobileSslWidget> {
@override
void dispose() {
if (changed) {
widget.proxyServer.flushConfig();
widget.proxyServer.configuration.flushConfig();
}
super.dispose();
}