mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-05-20 16:15:47 +08:00
212 lines
5.2 KiB
Dart
212 lines
5.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:network_proxy/network/util/file_read.dart';
|
|
import 'package:network_proxy/network/util/logger.dart';
|
|
|
|
/// @author wanghongen
|
|
/// 2023/7/26
|
|
/// 请求重写
|
|
class RequestRewrites {
|
|
bool enabled = true;
|
|
List<RequestRewriteRule> rules = [];
|
|
|
|
//单例
|
|
static RequestRewrites? _instance;
|
|
|
|
static Future<RequestRewrites> get instance async {
|
|
if (_instance == null) {
|
|
var config = await _loadRequestRewriteConfig();
|
|
_instance = RequestRewrites.fromJson(config);
|
|
}
|
|
return _instance!;
|
|
}
|
|
|
|
//加载配置
|
|
RequestRewrites.fromJson(Map<String, dynamic>? map) {
|
|
reload(map);
|
|
}
|
|
|
|
//重新加载配置
|
|
reload(Map<String, dynamic>? map) {
|
|
if (map == null) {
|
|
return;
|
|
}
|
|
|
|
enabled = map['enabled'] == true;
|
|
List? list = map['rules'];
|
|
rules.clear();
|
|
list?.forEach((element) {
|
|
try {
|
|
// body("重写消息体"), 兼容旧版本
|
|
if (element['type'] == '重写消息体' && element['requestBody']?.toString().isNotEmpty == true) {
|
|
element['type'] = RuleType.requestReplace.name;
|
|
rules.add(RequestRewriteRule.formJson(element));
|
|
} else if (element['type'] == '重写消息体' && element['responseBody']?.toString().isNotEmpty == true) {
|
|
element['type'] = RuleType.responseReplace.name;
|
|
rules.add(RequestRewriteRule.formJson(element));
|
|
} else {
|
|
rules.add(RequestRewriteRule.formJson(element));
|
|
}
|
|
} catch (e) {
|
|
logger.e('加载请求重写配置失败 $element', error: e);
|
|
}
|
|
});
|
|
}
|
|
|
|
///重新加载请求重写
|
|
Future<void> reloadRequestRewrite() async {
|
|
var config = await _loadRequestRewriteConfig();
|
|
reload(config);
|
|
}
|
|
|
|
/// 加载请求重写配置文件
|
|
static Future<Map<String, dynamic>?> _loadRequestRewriteConfig() async {
|
|
var home = await FileRead.homeDir();
|
|
var file = File('${home.path}${Platform.pathSeparator}request_rewrite.json');
|
|
var exits = await file.exists();
|
|
if (!exits) {
|
|
return null;
|
|
}
|
|
|
|
Map<String, dynamic> config = jsonDecode(await file.readAsString());
|
|
logger.i('加载请求重写配置文件 [$file]');
|
|
return config;
|
|
}
|
|
|
|
/// 查找重写规则
|
|
RequestRewriteRule? findRequestRewrite(String? url, RuleType type) {
|
|
if (!enabled || url == null) {
|
|
return null;
|
|
}
|
|
|
|
for (var rule in rules) {
|
|
if (rule.enabled && rule.urlReg.hasMatch(url) && type == rule.type) {
|
|
return rule;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// 查找重写规则
|
|
String? findResponseReplaceWith(String? url) {
|
|
if (!enabled || url == null) {
|
|
return null;
|
|
}
|
|
|
|
for (var rule in rules) {
|
|
if (rule.enabled && rule.urlReg.hasMatch(url) && rule.type == RuleType.responseReplace) {
|
|
return rule.responseBody;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
///添加规则
|
|
void addRule(RequestRewriteRule rule) {
|
|
rules.removeWhere((it) => it.url == rule.url);
|
|
rules.add(rule);
|
|
}
|
|
|
|
removeIndex(List<int> indexes) {
|
|
for (var i in indexes) {
|
|
rules.removeAt(i);
|
|
}
|
|
}
|
|
|
|
toJson() {
|
|
return {
|
|
'enabled': enabled,
|
|
'rules': rules.map((e) => e.toJson()).toList(),
|
|
};
|
|
}
|
|
|
|
/// 保存请求重写配置文件
|
|
Future<void> flushRequestRewriteConfig() async {
|
|
var home = await FileRead.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(toJson());
|
|
logger.i('刷新请求重写配置文件 ${file.path}');
|
|
await file.writeAsString(json);
|
|
}
|
|
}
|
|
|
|
enum RuleType {
|
|
// body("重写消息体"), //OLD VERSION
|
|
|
|
requestReplace("替换请求"),
|
|
responseReplace("替换响应"),
|
|
// header("重写Header"),
|
|
redirect("重定向");
|
|
|
|
//名称
|
|
final String label;
|
|
|
|
const RuleType(this.label);
|
|
|
|
static RuleType fromName(String name) {
|
|
return values.firstWhere((element) => element.name == name || element.label == name);
|
|
}
|
|
}
|
|
|
|
class RequestRewriteRule {
|
|
bool enabled = false;
|
|
RuleType type;
|
|
|
|
String? name;
|
|
String url;
|
|
|
|
//消息体
|
|
String? queryParam;
|
|
String? requestBody;
|
|
String? responseBody;
|
|
|
|
//重定向
|
|
String? redirectUrl;
|
|
|
|
RegExp urlReg;
|
|
|
|
RequestRewriteRule(this.enabled,
|
|
{this.name,
|
|
required this.url,
|
|
required this.type,
|
|
this.queryParam,
|
|
this.requestBody,
|
|
this.responseBody,
|
|
this.redirectUrl})
|
|
: urlReg = RegExp(url.replaceAll("*", ".*"));
|
|
|
|
/// 从json中创建
|
|
factory RequestRewriteRule.formJson(Map<dynamic, dynamic> map) {
|
|
return RequestRewriteRule(map['enabled'] == true,
|
|
name: map['name'],
|
|
url: map['url'] ?? map['domain'] + map['path'],
|
|
type: RuleType.fromName(map['type']),
|
|
queryParam: map['queryParam'],
|
|
requestBody: map['requestBody'],
|
|
responseBody: map['responseBody'],
|
|
redirectUrl: map['redirectUrl']);
|
|
}
|
|
|
|
void updatePathReg() {
|
|
urlReg = RegExp(url.replaceAll("*", ".*"));
|
|
}
|
|
|
|
toJson() {
|
|
return {
|
|
'name': name,
|
|
'enabled': enabled,
|
|
'url': url,
|
|
'type': type.name,
|
|
'queryParam': queryParam,
|
|
'requestBody': requestBody,
|
|
'responseBody': responseBody,
|
|
'redirectUrl': redirectUrl,
|
|
};
|
|
}
|
|
}
|