mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-05-10 00:44:12 +08:00
Fix external proxy to forward to each other issue
This commit is contained in:
@@ -109,7 +109,7 @@ class ProxyVpnService : VpnService(), ProtectSocket {
|
||||
allowPackages: ArrayList<String>?,
|
||||
disallowPackages: ArrayList<String>?
|
||||
) {
|
||||
Log.i("ProxyVpnService", "startVpn $host:$port $allowApps")
|
||||
Log.i("ProxyVpnService", "startVpn $proxyHost:$proxyPort $allowPackages")
|
||||
|
||||
host = proxyHost
|
||||
port = proxyPort
|
||||
|
||||
@@ -74,8 +74,8 @@ class VpnServicePlugin : AndroidFlutterPlugin() {
|
||||
private fun startVpn(
|
||||
host: String,
|
||||
port: Int,
|
||||
allowApps: ArrayList<String>?,
|
||||
disallowApps: ArrayList<String>?
|
||||
allowApps: ArrayList<String>? = arrayListOf(),
|
||||
disallowApps: ArrayList<String>? = arrayListOf(),
|
||||
) {
|
||||
val intent = ProxyVpnService.startVpnIntent(activity, host, port, allowApps, disallowApps)
|
||||
activity.startService(intent)
|
||||
|
||||
BIN
assets/icon.png
BIN
assets/icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
@@ -7,11 +7,11 @@ class Vpn {
|
||||
static bool isVpnStarted = false; //vpn是否已经启动
|
||||
|
||||
static startVpn(String host, int port, Configuration configuration) {
|
||||
List<String>? appList = configuration.appWhitelistEnabled ? configuration.appWhitelist : null;
|
||||
List<String>? appList = configuration.appWhitelistEnabled ? configuration.appWhitelist : [];
|
||||
|
||||
List<String>? disallowApps;
|
||||
if (appList == null || appList.isEmpty) {
|
||||
disallowApps = configuration.appBlacklist;
|
||||
if (appList.isEmpty) {
|
||||
disallowApps = configuration.appBlacklist ?? [];
|
||||
}
|
||||
|
||||
proxyVpnChannel.invokeMethod(
|
||||
@@ -26,11 +26,11 @@ class Vpn {
|
||||
|
||||
//重启vpn
|
||||
static restartVpn(String host, int port, Configuration configuration) {
|
||||
List<String>? appList = configuration.appWhitelistEnabled ? configuration.appWhitelist : null;
|
||||
List<String>? appList = configuration.appWhitelistEnabled ? configuration.appWhitelist : [];
|
||||
|
||||
List<String>? disallowApps;
|
||||
if (appList == null || appList.isEmpty) {
|
||||
disallowApps = configuration.appBlacklist;
|
||||
if (appList.isEmpty) {
|
||||
disallowApps = configuration.appBlacklist ?? [];
|
||||
}
|
||||
proxyVpnChannel.invokeMethod(
|
||||
"restartVpn", {"proxyHost": host, "proxyPort": port, "allowApps": appList, "disallowApps": disallowApps});
|
||||
|
||||
@@ -81,7 +81,19 @@ class Channel {
|
||||
|
||||
Socket get socket => _socket;
|
||||
|
||||
secureSocket(SecureSocket secureSocket, ChannelContext channelContext) {
|
||||
Future<SecureSocket> secureSocket(ChannelContext channelContext,
|
||||
{String? host, List<String>? supportedProtocols}) async {
|
||||
SecureSocket secureSocket = await SecureSocket.secure(socket,
|
||||
host: host, supportedProtocols: supportedProtocols, onBadCertificate: (certificate) => true);
|
||||
|
||||
_socket = secureSocket;
|
||||
_socket.done.then((value) => isOpen = false);
|
||||
pipeline.listen(this, channelContext);
|
||||
|
||||
return secureSocket;
|
||||
}
|
||||
|
||||
serverSecureSocket(SecureSocket secureSocket, ChannelContext channelContext) {
|
||||
_socket = secureSocket;
|
||||
_socket.done.then((value) => isOpen = false);
|
||||
pipeline.listen(this, channelContext);
|
||||
@@ -275,9 +287,7 @@ class ChannelPipeline extends ChannelHandler<Uint8List> {
|
||||
Channel? remoteChannel =
|
||||
channelContext.serverChannel ?? await channelContext.connectServerChannel(remote, RelayHandler(clientChannel));
|
||||
if (clientChannel.isSsl && !remoteChannel.isSsl) {
|
||||
SecureSocket secureSocket = await SecureSocket.secure(remoteChannel.socket,
|
||||
host: channelContext.getAttribute(AttributeKeys.domain), onBadCertificate: (certificate) => true);
|
||||
remoteChannel.secureSocket(secureSocket, channelContext);
|
||||
await remoteChannel.secureSocket(channelContext, host: channelContext.getAttribute(AttributeKeys.domain));
|
||||
}
|
||||
|
||||
relay(clientChannel, remoteChannel);
|
||||
@@ -348,7 +358,6 @@ class ChannelPipeline extends ChannelHandler<Uint8List> {
|
||||
data.packageSize = length;
|
||||
data.remoteAddress = '${channel.remoteSocketAddress.host}:${channel.remoteSocketAddress.port}';
|
||||
data.request ??= channelContext.currentRequest;
|
||||
channelContext.currentRequest?.response = data;
|
||||
}
|
||||
|
||||
//websocket协议
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:network_proxy/network/components/host_filter.dart';
|
||||
@@ -52,6 +51,7 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
|
||||
|
||||
@override
|
||||
void channelRead(ChannelContext channelContext, Channel channel, HttpRequest msg) async {
|
||||
|
||||
//下载证书
|
||||
if (msg.uri == 'http://proxy.pin/ssl' || msg.requestUrl == 'http://127.0.0.1:${channel.socket.port}/ssl') {
|
||||
ProxyHelper.crtDownload(channel, msg);
|
||||
@@ -64,9 +64,13 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
|
||||
}
|
||||
|
||||
//代理转发请求
|
||||
forward(channelContext, channel, msg).catchError((error, trace) {
|
||||
try {
|
||||
forward(channelContext, channel, msg).catchError((error, trace) {
|
||||
exceptionCaught(channelContext, channel, error, trace: trace);
|
||||
});
|
||||
} catch (error, trace) {
|
||||
exceptionCaught(channelContext, channel, error, trace: trace);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -95,11 +99,14 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
|
||||
try {
|
||||
remoteChannel = await _getRemoteChannel(channelContext, channel, httpRequest);
|
||||
} catch (error) {
|
||||
channel.error = error; //记录异常
|
||||
//https代理新建连接请求
|
||||
log.e("[${channel.id}] 连接异常 ${httpRequest.method.name} ${httpRequest.requestUrl}", error: error);
|
||||
if (httpRequest.method == HttpMethod.connect) {
|
||||
channel.error = error; //记录异常
|
||||
//https代理新建connect连接请求 返回ok 会继续发起正常请求 可以获取到请求内容
|
||||
await channel.write(
|
||||
HttpResponse(HttpStatus.ok.reason('Connection established'), protocolVersion: httpRequest.protocolVersion));
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -176,17 +183,28 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
|
||||
HostAndPort? remote = channelContext.getAttribute(AttributeKeys.remote);
|
||||
//外部代理
|
||||
ProxyInfo? proxyInfo = channelContext.getAttribute(AttributeKeys.proxyInfo);
|
||||
|
||||
if (remote != null || proxyInfo != null) {
|
||||
HostAndPort connectHost = remote ?? HostAndPort.host(proxyInfo!.host, proxyInfo.port!);
|
||||
var proxyChannel = await connectRemote(channelContext, clientChannel, connectHost);
|
||||
final proxyChannel = await connectRemote(channelContext, clientChannel, connectHost);
|
||||
|
||||
//代理建立完连接判断是否是https 需要发起connect请求
|
||||
if (httpRequest.method == HttpMethod.connect) {
|
||||
proxyChannel.write(httpRequest);
|
||||
await proxyChannel.write(httpRequest);
|
||||
} else {
|
||||
await HttpClients.connectRequest(hostAndPort, proxyChannel);
|
||||
if (clientChannel.isSsl) {
|
||||
await proxyChannel.secureSocket(channelContext, host: hostAndPort.host);
|
||||
}
|
||||
}
|
||||
|
||||
return proxyChannel;
|
||||
}
|
||||
|
||||
var proxyChannel = await connectRemote(channelContext, clientChannel, hostAndPort);
|
||||
final proxyChannel = await connectRemote(channelContext, clientChannel, hostAndPort);
|
||||
if (clientChannel.isSsl) {
|
||||
await proxyChannel.secureSocket(channelContext, host: hostAndPort.host);
|
||||
}
|
||||
|
||||
//https代理新建连接请求
|
||||
if (httpRequest.method == HttpMethod.connect) {
|
||||
await clientChannel.write(
|
||||
@@ -199,12 +217,6 @@ class HttpProxyChannelHandler extends ChannelHandler<HttpRequest> {
|
||||
Future<Channel> connectRemote(ChannelContext channelContext, Channel clientChannel, HostAndPort connectHost) async {
|
||||
var proxyHandler = HttpResponseProxyHandler(clientChannel, listener: listener, requestRewrites: requestRewrites);
|
||||
var proxyChannel = await channelContext.connectServerChannel(connectHost, proxyHandler);
|
||||
|
||||
if (clientChannel.isSsl) {
|
||||
SecureSocket secureSocket = await SecureSocket.secure(proxyChannel.socket,
|
||||
host: connectHost.host, onBadCertificate: (certificate) => true);
|
||||
proxyChannel.secureSocket(secureSocket, channelContext);
|
||||
}
|
||||
return proxyChannel;
|
||||
}
|
||||
}
|
||||
@@ -222,6 +234,7 @@ class HttpResponseProxyHandler extends ChannelHandler<HttpResponse> {
|
||||
@override
|
||||
void channelRead(ChannelContext channelContext, Channel channel, HttpResponse msg) async {
|
||||
var request = channelContext.currentRequest;
|
||||
request?.response = msg;
|
||||
|
||||
//域名是否过滤
|
||||
if (HostFilter.filter(request?.hostAndPort?.host) || request?.method == HttpMethod.connect) {
|
||||
|
||||
@@ -54,6 +54,18 @@ class HttpClients {
|
||||
return channel;
|
||||
}
|
||||
|
||||
await connectRequest(hostAndPort, channel);
|
||||
|
||||
if (hostAndPort.isSsl()) {
|
||||
await channel.secureSocket(channelContext);
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
///发起代理连接请求
|
||||
static Future<Channel> connectRequest(HostAndPort hostAndPort, Channel channel) async {
|
||||
ChannelHandler handler = channel.pipeline.handler;
|
||||
//代理 发送connect请求
|
||||
var httpResponseHandler = HttpResponseHandler();
|
||||
channel.pipeline.handler = httpResponseHandler;
|
||||
@@ -62,14 +74,13 @@ class HttpClients {
|
||||
proxyRequest.headers.set(HttpHeaders.hostHeader, '${hostAndPort.host}:${hostAndPort.port}');
|
||||
|
||||
await channel.write(proxyRequest);
|
||||
var response = await httpResponseHandler.getResponse(const Duration(seconds: 3));
|
||||
var response = await httpResponseHandler.getResponse(const Duration(seconds: 5));
|
||||
|
||||
channel.pipeline.handler = handler;
|
||||
|
||||
if (!response.status.isSuccessful()) {
|
||||
final error = "$hostAndPort Proxy failed to establish tunnel "
|
||||
"(${response.status.code} ${response..status.reasonPhrase})";
|
||||
throw Exception(error);
|
||||
throw Exception("$hostAndPort Proxy failed to establish tunnel "
|
||||
"(${response.status.code} ${response..status.reasonPhrase})");
|
||||
}
|
||||
|
||||
return channel;
|
||||
@@ -120,12 +131,8 @@ class HttpClients {
|
||||
ChannelContext channelContext = ChannelContext();
|
||||
var httpResponseHandler = HttpResponseHandler();
|
||||
HostAndPort hostPort = HostAndPort.of(request.uri);
|
||||
Channel channel = await proxyConnect(proxyInfo: proxyInfo, hostPort, httpResponseHandler, channelContext);
|
||||
|
||||
if (hostPort.isSsl()) {
|
||||
var secureSocket = await SecureSocket.secure(channel.socket, onBadCertificate: (certificate) => true);
|
||||
channel.secureSocket(secureSocket, channelContext);
|
||||
}
|
||||
Channel channel = await proxyConnect(proxyInfo: proxyInfo, hostPort, httpResponseHandler, channelContext);
|
||||
|
||||
await channel.write(request);
|
||||
return httpResponseHandler.getResponse(timeout).whenComplete(() => channel.close());
|
||||
|
||||
@@ -118,9 +118,6 @@ class Server extends Network {
|
||||
|
||||
//ssl握手
|
||||
if (hostAndPort?.isSsl() == true || TLS.isTLSClientHello(data)) {
|
||||
if (hostAndPort?.scheme == HostAndPort.httpScheme) {
|
||||
hostAndPort?.scheme = HostAndPort.httpsScheme;
|
||||
}
|
||||
ssl(channelContext, channel, data);
|
||||
return;
|
||||
}
|
||||
@@ -158,9 +155,7 @@ class Server extends Network {
|
||||
|
||||
if (remoteChannel != null && !remoteChannel.isSsl) {
|
||||
var supportProtocols = configuration.enabledHttp2 ? TLS.supportProtocols(data) : null;
|
||||
var secureSocket = await SecureSocket.secure(remoteChannel.socket,
|
||||
supportedProtocols: supportProtocols, host: hostAndPort.host, onBadCertificate: (certificate) => true);
|
||||
remoteChannel.secureSocket(secureSocket, channelContext);
|
||||
await remoteChannel.secureSocket(channelContext, host: hostAndPort.host, supportedProtocols: supportProtocols);
|
||||
}
|
||||
|
||||
//ssl自签证书
|
||||
@@ -168,9 +163,9 @@ class Server extends Network {
|
||||
var selectedProtocol = remoteChannel?.selectedProtocol;
|
||||
if (selectedProtocol != null) certificate.setAlpnProtocols([selectedProtocol], true);
|
||||
|
||||
//服务端等待客户端ssl握手
|
||||
//处理客户端ssl握手
|
||||
var secureSocket = await SecureSocket.secureServer(channel.socket, certificate, bufferedData: data);
|
||||
channel.secureSocket(secureSocket, channelContext);
|
||||
channel.serverSecureSocket(secureSocket, channelContext);
|
||||
} catch (error, trace) {
|
||||
try {
|
||||
channelContext.processInfo =
|
||||
|
||||
@@ -44,9 +44,9 @@ String getPackage(HttpMessage? message) {
|
||||
return "";
|
||||
}
|
||||
if (size > 1024 * 1024) {
|
||||
return "${(size / 1024 / 1024).toStringAsFixed(2)}MB";
|
||||
return "${(size / 1024 / 1024).toStringAsFixed(2)}M";
|
||||
}
|
||||
return "${(size / 1024).toStringAsFixed(2)}KB";
|
||||
return "${(size / 1024).toStringAsFixed(2)}K";
|
||||
}
|
||||
|
||||
String copyRequest(HttpRequest request, HttpResponse? response) {
|
||||
|
||||
@@ -26,7 +26,7 @@ class AppConfiguration {
|
||||
Locale? _language;
|
||||
|
||||
//是否显示更新内容公告
|
||||
bool upgradeNoticeV9 = true;
|
||||
bool upgradeNoticeV10 = true;
|
||||
|
||||
/// 是否启用画中画
|
||||
ValueNotifier<bool> pipEnabled = ValueNotifier(true);
|
||||
@@ -117,7 +117,7 @@ class AppConfiguration {
|
||||
var mode =
|
||||
ThemeMode.values.firstWhere((element) => element.name == config['mode'], orElse: () => ThemeMode.system);
|
||||
_theme = ThemeModel(mode: mode, useMaterial3: config['useMaterial3'] ?? true);
|
||||
upgradeNoticeV9 = config['upgradeNoticeV9'] ?? true;
|
||||
upgradeNoticeV10 = config['upgradeNoticeV10'] ?? true;
|
||||
_language = config['language'] == null ? null : Locale.fromSubtags(languageCode: config['language']);
|
||||
pipEnabled.value = config['pipEnabled'] ?? true;
|
||||
pipIcon.value = config['pipIcon'] ?? false;
|
||||
@@ -144,7 +144,7 @@ class AppConfiguration {
|
||||
return {
|
||||
'mode': _theme.mode.name,
|
||||
'useMaterial3': _theme.useMaterial3,
|
||||
'upgradeNoticeV9': upgradeNoticeV9,
|
||||
'upgradeNoticeV10': upgradeNoticeV10,
|
||||
"language": _language?.languageCode,
|
||||
'pipEnabled': pipEnabled.value,
|
||||
'pipIcon': pipIcon.value ? true : null,
|
||||
|
||||
@@ -85,7 +85,7 @@ class _DesktopHomePagePageState extends State<DesktopHomePage> implements EventL
|
||||
proxyServer.addListener(this);
|
||||
panel = NetworkTabController(tabStyle: const TextStyle(fontSize: 16), proxyServer: proxyServer);
|
||||
|
||||
if (widget.appConfiguration.upgradeNoticeV9) {
|
||||
if (widget.appConfiguration.upgradeNoticeV10) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showUpgradeNotice();
|
||||
});
|
||||
@@ -164,6 +164,7 @@ class _DesktopHomePagePageState extends State<DesktopHomePage> implements EventL
|
||||
});
|
||||
}
|
||||
|
||||
//left menu eg: requests, favorites, history, toolbox
|
||||
Widget leftNavigation(int index) {
|
||||
return NavigationRail(
|
||||
minWidth: 58,
|
||||
@@ -191,29 +192,33 @@ class _DesktopHomePagePageState extends State<DesktopHomePage> implements EventL
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
widget.appConfiguration.upgradeNoticeV9 = false;
|
||||
widget.appConfiguration.upgradeNoticeV10 = false;
|
||||
widget.appConfiguration.flushConfig();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(localizations.cancel))
|
||||
],
|
||||
title: Text(isCN ? '更新内容V1.0.9' : "Update content V1.0.9", style: const TextStyle(fontSize: 18)),
|
||||
title: Text(isCN ? '更新内容V1.1.0' : "Update content V1.1.0", style: const TextStyle(fontSize: 18)),
|
||||
content: Text(
|
||||
isCN
|
||||
? '提示:默认不会开启HTTPS抓包,请安装证书后再开启HTTPS抓包。\n'
|
||||
'点击HTTPS抓包(加锁图标),选择安装根证书,按照提示操作即可。\n\n'
|
||||
'1. 展示请求发起的应用图标;\n'
|
||||
'2. 关键词匹配高亮;\n'
|
||||
'3. 脚本批量操作和导入导出;\n'
|
||||
'4. 脚本支持日志查看,通过console.log()输出;\n'
|
||||
'5. 设置增加自动开启抓包;\n'
|
||||
'1. 更改应用程序图标;\n'
|
||||
'2. 工具箱Javascript代码运行调试;\n'
|
||||
'3. 支持生成python requests代码;\n'
|
||||
'4. 修复mac重写不能选择文件;\n'
|
||||
'5. 高级重放请求支持随机间隔;\n'
|
||||
'6. 修复配置外部代理互相转发问题;\n'
|
||||
'7. 修复ssl握手包域名为空的导致请求失败问题;\n'
|
||||
: 'Tips:By default, HTTPS packet capture will not be enabled. Please install the certificate before enabling HTTPS packet capture。\n'
|
||||
'Click HTTPS Capture packets(Lock icon),Choose to install the root certificate and follow the prompts to proceed。\n\n'
|
||||
'1. Display the application icon initiated by the request;\n'
|
||||
'2. Keyword matching highlights;\n'
|
||||
'3. Script batch operations and import/export;\n'
|
||||
'4. The script supports log viewing, output through console.log();\n'
|
||||
'5. Setting Auto Start Recording Traffic',
|
||||
'1. Change app icon;\n'
|
||||
'2. Toolbox add javascript code run;\n'
|
||||
'3. Support generating Python request code;\n'
|
||||
'4. Fix Mac rewrite unable to select files;\n'
|
||||
'5. Custom repeat request support random interval;\n'
|
||||
'6. Fix external proxy to forward to each other issue;\n'
|
||||
'7. fix tls client hello data server_name is null bug',
|
||||
style: const TextStyle(fontSize: 14)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class _HttpState extends State<_HttpWidget> {
|
||||
message = widget.message;
|
||||
body = TextEditingController(text: widget.message?.bodyAsString);
|
||||
if (widget.message?.headers == null && !widget.readOnly) {
|
||||
initHeader["User-Agent"] = ["ProxyPin/1.0.9"];
|
||||
initHeader["User-Agent"] = ["ProxyPin/1.1.0"];
|
||||
initHeader["Accept"] = ["*/*"];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener, Li
|
||||
}
|
||||
});
|
||||
|
||||
if (widget.appConfiguration.upgradeNoticeV9) {
|
||||
if (widget.appConfiguration.upgradeNoticeV10) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showUpgradeNotice();
|
||||
});
|
||||
@@ -219,22 +219,24 @@ class MobileHomeState extends State<MobileHomePage> implements EventListener, Li
|
||||
|
||||
String content = isCN
|
||||
? '提示:默认不会开启HTTPS抓包,请安装证书后再开启HTTPS抓包。\n\n'
|
||||
'1. 展示请求发起的应用图标;\n'
|
||||
'2. 关键词匹配高亮;\n'
|
||||
'3. 脚本批量操作和导入导出;\n'
|
||||
'4. 脚本支持日志查看,通过console.log()输出;\n'
|
||||
'5. 设置增加自动开启抓包;\n'
|
||||
'6. Android证书下载优化;'
|
||||
'1. 更改应用程序图标;\n'
|
||||
'2. 工具箱Javascript代码运行调试;\n'
|
||||
'3. 支持生成python requests代码;\n'
|
||||
'4. 修复mac重写不能选择文件;\n'
|
||||
'5. 高级重放请求支持随机间隔;\n'
|
||||
'6. 修复配置外部代理互相转发问题;\n'
|
||||
'7. 修复ssl握手包域名为空的导致请求失败问题;\n'
|
||||
: 'Tips:By default, HTTPS packet capture will not be enabled. Please install the certificate before enabling HTTPS packet capture。\n\n'
|
||||
'Click HTTPS Capture packets(Lock icon),Choose to install the root certificate and follow the prompts to proceed。\n\n'
|
||||
'1. Display the application icon initiated by the request;\n'
|
||||
'2. Keyword matching highlights;\n'
|
||||
'3. Script batch operations and import/export;\n'
|
||||
'4. The script supports log viewing, output through console.log();\n'
|
||||
'5. Setting Auto Start Recording Traffic;\n'
|
||||
'6. Android certificate download optimization; \n';
|
||||
showAlertDialog(isCN ? '更新内容V1.0.9' : "Update content V1.0.9", content, () {
|
||||
widget.appConfiguration.upgradeNoticeV9 = false;
|
||||
'1. Change app icon;\n'
|
||||
'2. Toolbox add javascript code run;\n'
|
||||
'3. Support generating Python request code;\n'
|
||||
'4. Fix Mac rewrite unable to select files;\n'
|
||||
'5. Custom repeat request support random interval;\n'
|
||||
'6. Fix external proxy to forward to each other issue;\n'
|
||||
'7. fix tls client hello data server_name is null bug';
|
||||
showAlertDialog(isCN ? '更新内容V1.1.0' : "Update content V1.1.0", content, () {
|
||||
widget.appConfiguration.upgradeNoticeV10 = false;
|
||||
widget.appConfiguration.flushConfig();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ class RequestRowState extends State<RequestRow> {
|
||||
subtitle: Text.rich(
|
||||
maxLines: 1,
|
||||
TextSpan(children: [
|
||||
TextSpan(text: '#${widget.index} ', style: const TextStyle(fontSize: 12, color: Colors.teal)),
|
||||
TextSpan(text: subTitle, style: const TextStyle(fontSize: 12, color: Colors.grey)),
|
||||
TextSpan(text: '#${widget.index} ', style: const TextStyle(fontSize: 11, color: Colors.teal)),
|
||||
TextSpan(text: subTitle, style: const TextStyle(fontSize: 11, color: Colors.grey)),
|
||||
])),
|
||||
trailing: getIcon(response),
|
||||
contentPadding:
|
||||
|
||||
@@ -225,7 +225,7 @@ class _HttpState extends State<_HttpWidget> with AutomaticKeepAliveClientMixin {
|
||||
message = widget.message;
|
||||
body = widget.message?.bodyAsString;
|
||||
if (widget.message?.headers == null && !widget.readOnly) {
|
||||
initHeader["User-Agent"] = ["ProxyPin/1.0.9"];
|
||||
initHeader["User-Agent"] = ["ProxyPin/1.1.0"];
|
||||
initHeader["Accept"] = ["*/*"];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ class _AppWhitelistState extends State<AppWhitelist> {
|
||||
title: localizations.enable,
|
||||
subtitle: localizations.appWhitelistDescribe,
|
||||
onChanged: (val) {
|
||||
changed = true;
|
||||
configuration.appWhitelistEnabled = val;
|
||||
configuration.flushConfig();
|
||||
}),
|
||||
|
||||
@@ -22,7 +22,7 @@ class About extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(left: 10, right: 10),
|
||||
child: Text(isCN ? "全平台开源免费抓包软件" : "Full platform open source free capture HTTP(S) traffic software")),
|
||||
const SizedBox(height: 10),
|
||||
const Text("V1.0.9"),
|
||||
const Text("V1.1.0"),
|
||||
ListTile(
|
||||
title: const Text("Github"),
|
||||
trailing: const Icon(Icons.arrow_right),
|
||||
|
||||
@@ -65,7 +65,7 @@ class Har {
|
||||
title = title.contains("ProxyPin") ? title : "[ProxyPin]$title";
|
||||
har["log"] = {
|
||||
"version": "1.2",
|
||||
"creator": {"name": "ProxyPin", "version": "1.0.9"},
|
||||
"creator": {"name": "ProxyPin", "version": "1.1.0"},
|
||||
"pages": [
|
||||
{
|
||||
"title": title,
|
||||
|
||||
@@ -4,7 +4,7 @@ cd ../build/linux/x64/release
|
||||
rm -rf package
|
||||
mkdir -p package/DEBIAN
|
||||
echo "Package: ProxyPin" >> package/DEBIAN/control
|
||||
echo "Version: 1.0.9" >> package/DEBIAN/control
|
||||
echo "Version: 1.1.0" >> package/DEBIAN/control
|
||||
echo "Priority: optional" >> package/DEBIAN/control
|
||||
echo "Architecture: amd64" >> package/DEBIAN/control
|
||||
echo "Depends: ca-certificates" >> package/DEBIAN/control
|
||||
|
||||
@@ -2,7 +2,7 @@ name: network_proxy
|
||||
description: ProxyPin
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 1.0.9+9
|
||||
version: 1.1.0+9
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.2 <4.0.0'
|
||||
@@ -33,7 +33,7 @@ dependencies:
|
||||
flutter_toastr: ^1.0.3
|
||||
share_plus: ^8.0.2
|
||||
brotli: ^0.6.0
|
||||
file_selector: ^1.0.2
|
||||
file_selector: ^1.0.3
|
||||
flutter_js: ^0.8.0
|
||||
flutter_code_editor:
|
||||
file_picker: ^8.0.0
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
Reference in New Issue
Block a user