From a4221311eab13b8a9df8a5a87de6c13bdcc3aea5 Mon Sep 17 00:00:00 2001 From: wanghongenpin Date: Sun, 15 Sep 2024 13:53:20 +0800 Subject: [PATCH] Fix Websocket Response not displayed --- lib/network/channel.dart | 4 ++++ lib/network/handler.dart | 8 ++++++-- lib/network/http/content_type.dart | 2 +- lib/network/http/http.dart | 6 +++--- lib/ui/desktop/desktop.dart | 2 ++ lib/ui/desktop/request/request.dart | 10 +++++----- lib/ui/mobile/mobile.dart | 2 ++ lib/ui/mobile/request/domians.dart | 10 ++++++++-- lib/ui/mobile/setting/rewrite/rewrite_replace.dart | 4 ++-- 9 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/network/channel.dart b/lib/network/channel.dart index 4b7d1d8..ac22bc2 100644 --- a/lib/network/channel.dart +++ b/lib/network/channel.dart @@ -375,11 +375,15 @@ class ChannelPipeline extends ChannelHandler { //websocket协议 if (data is HttpResponse && data.isWebSocket && remoteChannel != null) { + data.request?.response = data; + channelContext.currentRequest?.hostAndPort?.scheme = channel.isSsl ? HostAndPort.wssScheme : HostAndPort.wsScheme; logger.d("webSocket ${data.request?.hostAndPort}"); remoteChannel.write(data); + channelContext.listener?.onResponse(channelContext, data); + var rawCodec = RawCodec(); channel.pipeline.handle(rawCodec, rawCodec, WebSocketChannelHandler(remoteChannel, data)); remoteChannel.pipeline.handle(rawCodec, rawCodec, WebSocketChannelHandler(channel, data.request!)); diff --git a/lib/network/handler.dart b/lib/network/handler.dart index 7aeb9b7..e3ba3db 100644 --- a/lib/network/handler.dart +++ b/lib/network/handler.dart @@ -328,8 +328,12 @@ class WebSocketChannelHandler extends ChannelHandler { @override void channelRead(ChannelContext channelContext, Channel channel, Uint8List msg) { proxyChannel.write(msg); - - var frame = decoder.decode(msg); + WebSocketFrame? frame; + try { + frame = decoder.decode(msg); + } catch (e) { + log.e("websocket decode error", error: e); + } if (frame == null) { return; } diff --git a/lib/network/http/content_type.dart b/lib/network/http/content_type.dart index 56626be..956c3fc 100644 --- a/lib/network/http/content_type.dart +++ b/lib/network/http/content_type.dart @@ -81,7 +81,7 @@ class MediaType { ///编码 String? get charset { - return parameters["charset"]; + return parameters["charset"]?.toLowerCase(); } ///获取默认编码 diff --git a/lib/network/http/http.dart b/lib/network/http/http.dart index e79d348..367eb2d 100644 --- a/lib/network/http/http.dart +++ b/lib/network/http/http.dart @@ -128,9 +128,9 @@ class HttpRequest extends HttpMessage { HttpRequest(this.method, this.uri, {String protocolVersion = "HTTP/1.1"}) : super(protocolVersion); String? remoteDomain() { - if (hostAndPort == null && !uri.startsWith("/")) { + if (hostAndPort == null && (!uri.startsWith("/") && uri.isNotEmpty)) { try { - var uri = Uri.parse(requestUrl); + var uri = Uri.parse(this.uri); return '${uri.scheme}://${uri.host}${uri.hasPort ? ':${uri.port}' : ''}'; } catch (e) { return null; @@ -139,7 +139,7 @@ class HttpRequest extends HttpMessage { return hostAndPort?.domain; } - String get requestUrl => uri.startsWith("/") ? '${remoteDomain()}$uri' : uri; + String get requestUrl => uri.startsWith("/") || uri.isEmpty ? '${remoteDomain()}$uri' : uri; /// 请求的uri Uri? get requestUri { diff --git a/lib/ui/desktop/desktop.dart b/lib/ui/desktop/desktop.dart index d87f06f..73ba389 100644 --- a/lib/ui/desktop/desktop.dart +++ b/lib/ui/desktop/desktop.dart @@ -157,6 +157,7 @@ class _DesktopHomePagePageState extends State implements EventL '6. 脚本增加rawBody原始字节参数, body支持字节数组修改;\n' '7. 修复脚本消息体编码错误导致错误响应;\n' '8. 修复Har导出serverIPAddress不正确;\n' + '9. 修复Websocket Response不展示;\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. Support multiple theme colors;\n' @@ -167,6 +168,7 @@ class _DesktopHomePagePageState extends State implements EventL '6. The script add rawBody raw byte parameter, body supports byte array modification;\n' '7. Fix script message body encoding error causing incorrect response;\n' '8. Fix export HAR serverIPAddress incorrect;\n' + '9. Fix Websocket Response not displayed;\n' '', style: const TextStyle(fontSize: 14)))); }); diff --git a/lib/ui/desktop/request/request.dart b/lib/ui/desktop/request/request.dart index 89f5553..27ebf6f 100644 --- a/lib/ui/desktop/request/request.dart +++ b/lib/ui/desktop/request/request.dart @@ -136,7 +136,7 @@ class _RequestWidgetState extends State { onClick: (_) { var requestUrl = widget.request.requestUrl; Clipboard.setData(ClipboardData(text: requestUrl)) - .then((value) => FlutterToastr.show(localizations.copied, context)); + .then((value) => FlutterToastr.show(localizations.copied, rootNavigator: true, context)); }), MenuItem( label: localizations.copy, @@ -146,25 +146,25 @@ class _RequestWidgetState extends State { label: localizations.copyCurl, onClick: (_) { Clipboard.setData(ClipboardData(text: curlRequest(widget.request))) - .then((value) => FlutterToastr.show(localizations.copied, context)); + .then((value) => FlutterToastr.show(localizations.copied, rootNavigator: true, context)); }), MenuItem( label: localizations.copyRequestResponse, onClick: (_) { Clipboard.setData(ClipboardData(text: copyRequest(widget.request, widget.response.get()))) - .then((value) => FlutterToastr.show(localizations.copied, context)); + .then((value) => FlutterToastr.show(localizations.copied, rootNavigator: true, context)); }), MenuItem( label: localizations.copyAsPythonRequests, onClick: (_) { Clipboard.setData(ClipboardData(text: copyAsPythonRequests(widget.request))) - .then((value) => FlutterToastr.show(localizations.copied, context)); + .then((value) => FlutterToastr.show(localizations.copied, rootNavigator: true, context)); }, ), ]), onClick: (_) { Clipboard.setData(ClipboardData(text: curlRequest(widget.request))) - .then((value) => FlutterToastr.show(localizations.copied, context)); + .then((value) => FlutterToastr.show(localizations.copied, rootNavigator: true, context)); }), MenuItem.separator(), MenuItem(label: localizations.repeat, onClick: (_) => onRepeat(widget.request)), diff --git a/lib/ui/mobile/mobile.dart b/lib/ui/mobile/mobile.dart index c1c2510..7a4eeb3 100644 --- a/lib/ui/mobile/mobile.dart +++ b/lib/ui/mobile/mobile.dart @@ -254,6 +254,7 @@ class MobileHomeState extends State implements EventListener, Li '7. 修复扫码链接多个IP优先级问题;\n' '8. 修复Transfer-Encoding有空格解析错误问题;\n' '9. 修复Har导出serverIPAddress不正确;\n' + '10. 修复Websocket Response不展示;\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. Support multiple theme colors;\n' @@ -265,6 +266,7 @@ class MobileHomeState extends State implements EventListener, Li '7. Fix the issue of scanning QR code to connect to multiple IP priorities;\n' '8. Fix header Transfer-Encoding with spaces;\n' '9. Fix export HAR serverIPAddress incorrect;\n' + '10. Fix Websocket Response not displayed;\n' ''; showAlertDialog(isCN ? '更新内容V1.1.3' : "Update content V1.1.3", content, () { widget.appConfiguration.upgradeNoticeV13 = false; diff --git a/lib/ui/mobile/request/domians.dart b/lib/ui/mobile/request/domians.dart index 7505f54..14d862e 100644 --- a/lib/ui/mobile/request/domians.dart +++ b/lib/ui/mobile/request/domians.dart @@ -102,7 +102,12 @@ class DomainListState extends State with AutomaticKeepAliveClientMix } addResponse(HttpResponse response) { - if (showHostAndPort == response.request?.hostAndPort) { + var hostAndPort = response.request!.hostAndPort; + if (response.isWebSocket && containerMap[hostAndPort]?.contains(response.request) == false) { + add(response.request!); + } + + if (showHostAndPort == hostAndPort) { requestSequenceKey.currentState?.addResponse(response); } } @@ -197,12 +202,13 @@ class DomainListState extends State with AutomaticKeepAliveClientMix onTap: () { Navigator.push(context, MaterialPageRoute(builder: (context) { showHostAndPort = view.elementAt(index); + print(containerMap.keys); return Scaffold( appBar: AppBar(title: Text(view.elementAt(index).domain, style: const TextStyle(fontSize: 16))), body: RequestSequence( key: requestSequenceKey, displayDomain: false, - container: ListenableList(containerMap[view.elementAt(index)]!), + container: ListenableList(containerMap[view.elementAt(index)]), onRemove: widget.onRemove, proxyServer: widget.proxyServer)); })); diff --git a/lib/ui/mobile/setting/rewrite/rewrite_replace.dart b/lib/ui/mobile/setting/rewrite/rewrite_replace.dart index 2660b70..2c6656a 100644 --- a/lib/ui/mobile/setting/rewrite/rewrite_replace.dart +++ b/lib/ui/mobile/setting/rewrite/rewrite_replace.dart @@ -64,9 +64,9 @@ class _RewriteReplaceState extends State { resizeToAvoidBottomInset: false, appBar: AppBar( title: ListTile( - title: Text(isCN ? widget.ruleType.name : widget.ruleType.name, + title: Text(isCN ? widget.ruleType.label : widget.ruleType.name, textAlign: TextAlign.center, style: const TextStyle(fontWeight: FontWeight.w500)), - subtitle: Text(widget.subtitle, + subtitle: Text(widget.subtitle.fixAutoLines(), maxLines: 1, textAlign: TextAlign.center, style: const TextStyle(fontSize: 12, color: Colors.grey))),