Skip to content

Commit

Permalink
详情增加快速请求重写
Browse files Browse the repository at this point in the history
  • Loading branch information
wanghongenpin committed Aug 26, 2023
1 parent 8cc1b83 commit cfd23cd
Show file tree
Hide file tree
Showing 11 changed files with 239 additions and 196 deletions.
2 changes: 1 addition & 1 deletion ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class FluentApp extends StatelessWidget {
builder: (_, current, __) {
uiConfiguration.theme = current;
uiConfiguration.flushConfig();
print(current.mode.name);

return MaterialApp(
title: 'ProxyPin',
debugShowCheckedModeBanner: false,
Expand Down
2 changes: 1 addition & 1 deletion lib/network/bin/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Configuration {
bool upgradeNotice = true;

//请求重写
RequestRewrites requestRewrites = RequestRewrites();
RequestRewrites requestRewrites = RequestRewrites.instance;

//外部代理
ProxyInfo? externalProxy;
Expand Down
11 changes: 9 additions & 2 deletions lib/network/util/request_rewrite.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@

/// @author wanghongen
/// 2023/7/26
class RequestRewrites {
bool enabled = true;
final List<RequestRewriteRule> rules = [];

RequestRewrites._();

//单例
static final RequestRewrites _instance = RequestRewrites._();

static RequestRewrites get instance => _instance;

load(Map<String, dynamic>? map) {
if (map == null) {
return;
Expand Down Expand Up @@ -47,7 +53,8 @@ class RequestRewrites {
return null;
}

addRule(RequestRewriteRule rule) {
void addRule(RequestRewriteRule rule) {
rules.removeWhere((it) => it.path == rule.path && it.domain == rule.domain);
rules.add(rule);
}

Expand Down
1 change: 1 addition & 0 deletions lib/storage/favorites.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class _Item {
_Item(this.request, [this.response]) {
response ??= request.response;
request.response = response;
response?.request = request;
}

factory _Item.fromJson(Map<String, dynamic> json) {
Expand Down
101 changes: 74 additions & 27 deletions lib/ui/content/body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:network_proxy/network/bin/configuration.dart';
import 'package:network_proxy/network/http/http.dart';
import 'package:network_proxy/network/util/request_rewrite.dart';
import 'package:network_proxy/ui/component/json/json_viewer.dart';
import 'package:network_proxy/ui/component/json/theme.dart';
import 'package:network_proxy/ui/component/utils.dart';
import 'package:network_proxy/ui/desktop/toolbar/setting/request_rewrite.dart';
import 'package:network_proxy/ui/mobile/setting/request_rewrite.dart';
import 'package:network_proxy/utils/num.dart';
import 'package:network_proxy/utils/platform.dart';
import 'package:window_manager/window_manager.dart';
Expand Down Expand Up @@ -99,30 +103,71 @@ class HttpBodyState extends State<HttpBodyWidget> {
return tabController;
}

/// 标题
Widget titleWidget({inNewWindow = false}) {
var type = widget.httpMessage is HttpRequest ? "Request" : "Response";

var list = [
Text('$type Body', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
const SizedBox(width: 15),
IconButton(
icon: const Icon(Icons.copy),
tooltip: '复制',
onPressed: () {
var body = bodyKey.currentState?.body;
if (body == null) {
return;
}
Clipboard.setData(ClipboardData(text: body)).then((value) => FlutterToastr.show("已复制到剪切板", context));
}),
];

if (!inNewWindow || Platforms.isMobile()) {
list.add(const SizedBox(width: 5));
list.add(IconButton(
icon: const Icon(Icons.edit_document),
tooltip: '请求重写',
onPressed: () {
HttpRequest? request;
if (widget.httpMessage is HttpRequest) {
request = widget.httpMessage as HttpRequest;
} else {
request = (widget.httpMessage as HttpResponse).request;
}

var body = bodyKey.currentState?.body;
var rule = RequestRewriteRule(true, request?.path() ?? '', request?.remoteDomain(),
requestBody: widget.httpMessage is HttpRequest ? body : null,
responseBody: widget.httpMessage is HttpResponse ? body : null);

if (Platforms.isMobile()) {
Navigator.push(context, MaterialPageRoute(builder: (_) => RewriteRule(rule: rule))).then((value) {
if (value is RequestRewriteRule) {
Configuration.instance.then((it) => it.flushRequestRewriteConfig());
}
});
} else {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => RuleAddDialog(rule: rule)).then((value) {
if (value != null) {
Configuration.instance.then((it) => it.flushRequestRewriteConfig());
FlutterToastr.show("添加请求重写规则成功", context);
}
});
}
}));
}

if (!inNewWindow) {
list.add(const SizedBox(width: 5));
list.add(IconButton(icon: const Icon(Icons.open_in_new), tooltip: '新窗口打开', onPressed: () => openNew()));
}

return Row(
mainAxisAlignment: widget.inNewWindow ? MainAxisAlignment.center : MainAxisAlignment.start,
children: [
Text('$type Body', style: const TextStyle(fontWeight: FontWeight.w500)),
const SizedBox(width: 15),
IconButton(
icon: const Icon(Icons.copy),
tooltip: '复制',
onPressed: () {
var body = bodyKey.currentState?.body;
if (body == null) {
return;
}

Clipboard.setData(ClipboardData(text: body)).then((value) => FlutterToastr.show("已复制到剪切板", context));
}),
const SizedBox(width: 5),
inNewWindow
? const SizedBox()
: IconButton(icon: const Icon(Icons.open_in_new), tooltip: '新窗口打开', onPressed: () => openNew())
],
children: list,
);
}

Expand Down Expand Up @@ -193,14 +238,16 @@ class _BodyState extends State<_Body> {
if (viewType == ViewType.hex) {
return message!.body!.map(intToHex).join(" ");
}
if (viewType == ViewType.formUrl) {
return Uri.decodeFull(message!.bodyAsString);
}
if (viewType == ViewType.jsonText || viewType == ViewType.json) {
//json格式化
var jsonObject = json.decode(message!.bodyAsString);
return const JsonEncoder.withIndent(" ").convert(jsonObject);
}
try {
if (viewType == ViewType.formUrl) {
return Uri.decodeFull(message!.bodyAsString);
}
if (viewType == ViewType.jsonText || viewType == ViewType.json) {
//json格式化
var jsonObject = json.decode(message!.bodyAsString);
return const JsonEncoder.withIndent(" ").convert(jsonObject);
}
} catch (_) {}
return message!.bodyAsString;
}

Expand Down
59 changes: 22 additions & 37 deletions lib/ui/desktop/toolbar/setting/request_rewrite.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,33 +97,29 @@ class _RequestRewriteState extends State<RequestRewrite> {
barrierDismissible: false,
builder: (BuildContext context) {
return RuleAddDialog(
requestRewrites: widget.configuration.requestRewrites,
currentIndex: currentIndex,
onChange: () {
changed = true;
requestRuleList.changeState();
});
});
rule: currentIndex >= 0 ? widget.configuration.requestRewrites.rules[currentIndex] : null);
}).then((value) {
if (value != null) {
changed = true;
requestRuleList.changeState();
}
});
}
}

///请求重写规则添加对话框
class RuleAddDialog extends StatelessWidget {
final RequestRewrites requestRewrites;
final int currentIndex;
final Function onChange;
final RequestRewriteRule? rule;

const RuleAddDialog({super.key, required this.currentIndex, required this.onChange, required this.requestRewrites});
const RuleAddDialog({super.key, this.currentIndex = -1, this.rule});

@override
Widget build(BuildContext context) {
GlobalKey formKey = GlobalKey<FormState>();
RequestRewriteRule? rule;
if (currentIndex >= 0) {
rule = requestRewrites.rules[currentIndex];
}

ValueNotifier<bool> enableNotifier = ValueNotifier(rule == null || rule.enabled);
ValueNotifier<bool> enableNotifier = ValueNotifier(rule == null || rule?.enabled == true);
String? domain = rule?.domain;
String? path = rule?.path;
String? requestBody = rule?.requestBody;
Expand Down Expand Up @@ -179,17 +175,18 @@ class RuleAddDialog extends StatelessWidget {
if ((formKey.currentState as FormState).validate()) {
(formKey.currentState as FormState).save();

var rule = RequestRewriteRule(
enableNotifier.value, path!, domain?.trim().isEmpty == true ? null : domain?.trim(),
requestBody: requestBody, responseBody: responseBody);

if (currentIndex >= 0) {
requestRewrites.rules[currentIndex] = RequestRewriteRule(enableNotifier.value, path!, domain,
requestBody: requestBody, responseBody: responseBody);
RequestRewrites.instance.rules[currentIndex] = rule;
} else {
requestRewrites.addRule(RequestRewriteRule(enableNotifier.value, path!, domain,
requestBody: requestBody, responseBody: responseBody));
RequestRewrites.instance.addRule(rule);
}

enableNotifier.dispose();
onChange.call();
Navigator.of(context).pop();
Navigator.of(context).pop(rule);
}
}),
ElevatedButton(
Expand All @@ -210,19 +207,10 @@ class RequestRuleList extends StatefulWidget {
State<RequestRuleList> createState() => _RequestRuleListState();

List<int> removeSelected() {
var index = currentSelectedIndex();
var state = (key as GlobalKey<_RequestRuleListState>).currentState;
List<int> list = [];
var selectedIndex = state?.currentSelectedIndex;
state?.selected.forEach((key, value) {
if (value == true) {
list.add(key);
if (selectedIndex == key) {
state.currentSelectedIndex = -1;
}
}
});
state?.selected.clear();
return list;
state?.currentSelectedIndex = -1;
return index >= 0 ? [index] : [];
}

int currentSelectedIndex() {
Expand All @@ -237,7 +225,6 @@ class RequestRuleList extends StatefulWidget {
}

class _RequestRuleListState extends State<RequestRuleList> {
final Map<int, bool> selected = {};
int currentSelectedIndex = -1;

changeState() {
Expand All @@ -248,8 +235,7 @@ class _RequestRuleListState extends State<RequestRuleList> {
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 10),
height: 300,
constraints: const BoxConstraints(minWidth: 500),
constraints: const BoxConstraints(minWidth: 500, minHeight: 300),
child: SingleChildScrollView(
child: DataTable(
columnSpacing: 36,
Expand Down Expand Up @@ -283,10 +269,9 @@ class _RequestRuleListState extends State<RequestRuleList> {
style: const TextStyle(fontSize: 12)),
))
],
selected: selected[index] == true,
selected: currentSelectedIndex == index,
onSelectChanged: (value) {
setState(() {
selected[index] = value!;
currentSelectedIndex = index;
});
})),
Expand Down
16 changes: 8 additions & 8 deletions lib/ui/mobile/mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener {
]),
drawer: DrawerWidget(proxyServer: proxyServer),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: SocketLaunch(
proxyServer: proxyServer,
startup: false,
size: 38,
onStart: () => Vpn.startVpn("127.0.0.1", proxyServer.port, proxyServer.configuration.appWhitelist),
onStop: () => Vpn.stopVpn())),
onPressed: null,
child: Center(
child: SocketLaunch(
proxyServer: proxyServer,
size: 36,
startup: false,
onStart: () => Vpn.startVpn("127.0.0.1", proxyServer.port, proxyServer.configuration.appWhitelist),
onStop: () => Vpn.stopVpn()))),
body: ValueListenableBuilder(
valueListenable: desktop,
builder: (context, value, _) {

return Column(children: [
value.connect ? remoteConnect(value) : const SizedBox(),
Expanded(child: RequestListWidget(key: requestStateKey, proxyServer: proxyServer))
Expand Down
Loading

0 comments on commit cfd23cd

Please sign in to comment.