XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEExtension

【DLL】XFE各类拓展是一个C#的DLL库,旨在优化C#代码中常用语句的使用,并提供更简洁的访问方式,同时提供Xunit测试框架,快速搭建服务器/客户端,免费ChatGPTAPI接口,免费通讯服务器,XFE下载器,新增格式等

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFEExtension

公开本地监听端口属性,兼容多端口场景

CyberComm 请求上下文和 WebSocket 事件参数现已公开实际本地监听端口(LocalPort),便于在 CDN/反向代理与后端端口不一致时获取真实端口。相关方法和事件参数构造函数已调整以支持 localPort 传递和记录,CyberCommRequestEventArgs 也新增 LocalPort 属性,兼容旧 HttpListener 模式。版本号升级至 5.2.1,NuGet 包发布说明同步更新。

7a588e6
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

6 个文件 +44 -24
Modified XFEExtension.NetCore/CyberComm/CyberCommHttp.cs +4 -0
@@ -17,6 +17,7 @@ public sealed class CyberCommHttpRequestContext
17 17 IReadOnlyDictionary<string, IReadOnlyList<string>> query,
18 18 ReadOnlyMemory<byte> body,
19 19 string clientIp,
20 int localPort,
20 21 string correlationId)
21 22 {
22 23 RequestUri = requestUri;
@@ -25,6 +26,7 @@ public sealed class CyberCommHttpRequestContext
25 26 Query = query;
26 27 Body = body;
27 28 ClientIp = clientIp;
29 LocalPort = localPort;
28 30 CorrelationId = correlationId;
29 31 }
30 32
@@ -35,6 +37,8 @@ public sealed class CyberCommHttpRequestContext
35 37 public ReadOnlyMemory<byte> Body { get; }
36 38 public string RequestBody => Encoding.UTF8.GetString(Body.Span);
37 39 public string ClientIp { get; }
40 /// <summary>实际接受当前连接的本地监听端口,不受 Host 请求头或反向代理公开端口影响。</summary>
41 public int LocalPort { get; }
38 42 public string CorrelationId { get; }
39 43 public CyberCommHttpResponse Response { get; } = new();
40 44 }
Modified XFEExtension.NetCore/CyberComm/CyberCommRequestEventArgs.cs +2 -0
@@ -53,6 +53,8 @@ public abstract record CyberCommRequestEventArgs
53 53 public HttpListenerResponse? Response => _response;
54 54
55 55 public string ClientIP { get; }
56 /// <summary>实际接受当前连接的本地监听端口;旧 HttpListener 兼容模式下取请求 URL 端口。</summary>
57 public int LocalPort => Context?.LocalPort ?? RequestUrl?.Port ?? 0;
56 58 /// <summary>贯穿请求、响应和日志的关联标识。</summary>
57 59 public string CorrelationId => Context?.CorrelationId ?? string.Empty;
58 60
Modified XFEExtension.NetCore/CyberComm/CyberCommServer.cs +22 -16
@@ -345,6 +345,7 @@ public sealed class CyberCommServer : IAsyncDisposable
345 345 {
346 346 using (client)
347 347 {
348 var localPort = ((IPEndPoint?)client.Client.LocalEndPoint)?.Port ?? endpoint.Port;
348 349 Stream stream = client.GetStream();
349 350 if (endpoint.UseTls)
350 351 {
@@ -393,14 +394,14 @@ public sealed class CyberCommServer : IAsyncDisposable
393 394 {
394 395 connection.IsWebSocket = true;
395 396 var webSocketStream = reader.DetachStream();
396 await ProcessWebSocketAsync(webSocketStream, request, options, clientIp, connection, serverToken).ConfigureAwait(false);
397 await ProcessWebSocketAsync(webSocketStream, request, options, clientIp, localPort, connection, serverToken).ConfigureAwait(false);
397 398 return;
398 399 }
399 400
400 401 connection.IsHandlingRequest = true;
401 402 try
402 403 {
403 await ProcessHttpRequestAsync(stream, request, options, clientIp, serverToken).ConfigureAwait(false);
404 await ProcessHttpRequestAsync(stream, request, options, clientIp, localPort, serverToken).ConfigureAwait(false);
404 405 }
405 406 finally
406 407 {
@@ -426,10 +427,12 @@ public sealed class CyberCommServer : IAsyncDisposable
426 427 }
427 428 }
428 429
429 private async Task ProcessHttpRequestAsync(Stream stream, CyberCommParsedRequest request, CyberCommServerOptions options, string clientIp, CancellationToken serverToken)
430 private async Task ProcessHttpRequestAsync(Stream stream, CyberCommParsedRequest request, CyberCommServerOptions options,
431 string clientIp, int localPort, CancellationToken serverToken)
430 432 {
431 433 var body = options.ReadHttpRequestBody ? request.Body : ReadOnlyMemory<byte>.Empty;
432 var context = new CyberCommHttpRequestContext(request.RequestUri, request.Method, request.Headers, request.Query, body, clientIp, Guid.NewGuid().ToString("N"));
434 var context = new CyberCommHttpRequestContext(request.RequestUri, request.Method, request.Headers, request.Query,
435 body, clientIp, localPort, Guid.NewGuid().ToString("N"));
433 436 context.Response.Headers["X-Correlation-Id"] = context.CorrelationId;
434 437 using var handlerSource = CancellationTokenSource.CreateLinkedTokenSource(serverToken);
435 438 if (options.Limits.HandlerTimeout != Timeout.InfiniteTimeSpan)
@@ -479,7 +482,7 @@ public sealed class CyberCommServer : IAsyncDisposable
479 482 }
480 483
481 484 private async Task ProcessWebSocketAsync(Stream stream, CyberCommParsedRequest request, CyberCommServerOptions options,
482 string clientIp, ActiveConnection connection, CancellationToken serverToken)
485 string clientIp, int localPort, ActiveConnection connection, CancellationToken serverToken)
483 486 {
484 487 if (!ValidateWebSocketRequest(request, out var key))
485 488 {
@@ -497,33 +500,35 @@ public sealed class CyberCommServer : IAsyncDisposable
497 500 await using var peer = new CyberCommWebSocketPeer(webSocket, options.Limits);
498 501 connection.Peer = peer;
499 502 var headers = ToNameValueCollection(request.Headers);
500 var connectedArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket, string.Empty, clientIp, headers, true).WithTransport(peer);
503 var connectedArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket, string.Empty, clientIp, headers, true, localPort).WithTransport(peer);
501 504 await InvokeWebSocketHandlerAsync(WebSocketConnectedHandler, ClientConnected, connectedArgs, serverToken).ConfigureAwait(false);
502 505
503 506 try
504 507 {
505 await ReceiveWebSocketMessagesAsync(webSocket, peer, request.RequestUri, headers, clientIp, options, serverToken).ConfigureAwait(false);
508 await ReceiveWebSocketMessagesAsync(webSocket, peer, request.RequestUri, headers, clientIp, localPort, options, serverToken).ConfigureAwait(false);
506 509 }
507 510 catch (OperationCanceledException) when (serverToken.IsCancellationRequested)
508 511 {
509 512 }
510 513 catch (Exception ex)
511 514 {
512 var errorArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket, new XFECyberCommException("与客户端通讯期间发生异常", ex), clientIp, headers).WithTransport(peer);
515 var errorArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket,
516 new XFECyberCommException("与客户端通讯期间发生异常", ex), clientIp, headers, localPort).WithTransport(peer);
513 517 await InvokeWebSocketHandlerAsync(WebSocketMessageHandler, MessageReceived, errorArgs, serverToken).ConfigureAwait(false);
514 518 }
515 519 finally
516 520 {
517 521 if (webSocket.State is WebSocketState.Open or WebSocketState.CloseReceived)
518 522 await peer.CloseAsync(WebSocketCloseStatus.NormalClosure, "Connection Closed", serverToken).ConfigureAwait(false);
519 var closedArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket, string.Empty, clientIp, headers, true).WithTransport(peer);
523 var closedArgs = new CyberCommServerEventArgsImpl(request.RequestUri, webSocket, string.Empty, clientIp, headers, true, localPort).WithTransport(peer);
520 524 await InvokeWebSocketHandlerAsync(WebSocketClosedHandler, ConnectionClosed, closedArgs, CancellationToken.None).ConfigureAwait(false);
521 525 connection.Peer = null;
522 526 }
523 527 }
524 528
525 529 private async Task ReceiveWebSocketMessagesAsync(WebSocket webSocket, CyberCommWebSocketPeer peer, Uri requestUri,
526 NameValueCollection headers, string clientIp, CyberCommServerOptions options, CancellationToken cancellationToken)
530 NameValueCollection headers, string clientIp, int localPort, CyberCommServerOptions options,
531 CancellationToken cancellationToken)
527 532 {
528 533 var receiveSize = Math.Clamp(BufferLength, 1024, options.Limits.MaxWebSocketFrameBytes);
529 534 var buffer = new byte[receiveSize];
@@ -541,7 +546,7 @@ public sealed class CyberCommServer : IAsyncDisposable
541 546
542 547 if (!options.AssembleWebSocketMessages)
543 548 {
544 await PublishWebSocketMessageAsync(webSocket, peer, requestUri, headers, clientIp, result.MessageType,
549 await PublishWebSocketMessageAsync(webSocket, peer, requestUri, headers, clientIp, localPort, result.MessageType,
545 550 buffer.AsMemory(0, result.Count).ToArray(), result.EndOfMessage, false, cancellationToken).ConfigureAwait(false);
546 551 continue;
547 552 }
@@ -568,13 +573,14 @@ public sealed class CyberCommServer : IAsyncDisposable
568 573 return;
569 574 }
570 575 if (result.MessageType == WebSocketMessageType.Close) break;
571 await PublishWebSocketMessageAsync(webSocket, peer, requestUri, headers, clientIp, messageType, message.ToArray(), true, true, cancellationToken).ConfigureAwait(false);
576 await PublishWebSocketMessageAsync(webSocket, peer, requestUri, headers, clientIp, localPort,
577 messageType, message.ToArray(), true, true, cancellationToken).ConfigureAwait(false);
572 578 }
573 579 }
574 580
575 581 private async Task PublishWebSocketMessageAsync(WebSocket webSocket, CyberCommWebSocketPeer peer, Uri requestUri,
576 NameValueCollection headers, string clientIp, WebSocketMessageType messageType, byte[] payload, bool endOfMessage,
577 bool validateUtf8, CancellationToken cancellationToken)
582 NameValueCollection headers, string clientIp, int localPort, WebSocketMessageType messageType, byte[] payload,
583 bool endOfMessage, bool validateUtf8, CancellationToken cancellationToken)
578 584 {
579 585 CyberCommServerEventArgs args;
580 586 if (messageType == WebSocketMessageType.Text)
@@ -586,10 +592,10 @@ public sealed class CyberCommServer : IAsyncDisposable
586 592 await peer.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "Invalid UTF-8", cancellationToken).ConfigureAwait(false);
587 593 return;
588 594 }
589 args = new CyberCommServerEventArgsImpl(requestUri, webSocket, text, clientIp, headers, endOfMessage);
595 args = new CyberCommServerEventArgsImpl(requestUri, webSocket, text, clientIp, headers, endOfMessage, localPort);
590 596 }
591 597 else if (messageType == WebSocketMessageType.Binary)
592 args = new CyberCommServerEventArgsImpl(requestUri, webSocket, payload, clientIp, headers, endOfMessage);
598 args = new CyberCommServerEventArgsImpl(requestUri, webSocket, payload, clientIp, headers, endOfMessage, localPort);
593 599 else
594 600 throw new ArgumentOutOfRangeException(nameof(messageType));
595 601 await InvokeWebSocketHandlerAsync(WebSocketMessageHandler, MessageReceived, args.WithTransport(peer), cancellationToken).ConfigureAwait(false);
Modified XFEExtension.NetCore/CyberComm/CyberCommServerEventArgs.cs +9 -3
@@ -22,6 +22,9 @@ public abstract record CyberCommServerEventArgs(Uri? RequestUrl, BackMessageType
22 22 private Func<ReadOnlyMemory<byte>, WebSocketMessageType, CancellationToken, ValueTask<CyberCommSendResult>>? SendHandler { get; init; }
23 23 private Func<WebSocketCloseStatus, string, CancellationToken, ValueTask<CyberCommSendResult>>? CloseHandler { get; init; }
24 24
25 /// <summary>实际接受当前连接的本地监听端口,不受 Host 请求头或反向代理公开端口影响。</summary>
26 public int LocalPort { get; internal init; }
27
25 28 /// <summary>
26 29 /// 发送文本消息
27 30 /// </summary>
@@ -102,14 +105,17 @@ public abstract record CyberCommServerEventArgs(Uri? RequestUrl, BackMessageType
102 105 throw new XFECyberCommException("强制关闭服务器端连接时出现异常", ex);
103 106 }
104 107 }
105 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, string message, string ipAddress, NameValueCollection wsHeader, bool endOfMessage) : this(requestUrl, BackMessageType.Text, webSocket, wsHeader, null, ipAddress, message, null, endOfMessage)
108 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, string message, string ipAddress, NameValueCollection wsHeader, bool endOfMessage, int localPort) : this(requestUrl, BackMessageType.Text, webSocket, wsHeader, null, ipAddress, message, null, endOfMessage)
106 109 {
110 LocalPort = localPort;
107 111 }
108 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, byte[] bytes, string ipAddress, NameValueCollection wsHeader, bool endOfMessage) : this(requestUrl, BackMessageType.Binary, webSocket, wsHeader, null, ipAddress, null, bytes, endOfMessage)
112 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, byte[] bytes, string ipAddress, NameValueCollection wsHeader, bool endOfMessage, int localPort) : this(requestUrl, BackMessageType.Binary, webSocket, wsHeader, null, ipAddress, null, bytes, endOfMessage)
109 113 {
114 LocalPort = localPort;
110 115 }
111 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, XFECyberCommException ex, string ipAddress, NameValueCollection wsHeader) : this(requestUrl, BackMessageType.Error, webSocket, wsHeader, ex, ipAddress, null, null, true)
116 internal CyberCommServerEventArgs(Uri? requestUrl, WebSocket webSocket, XFECyberCommException ex, string ipAddress, NameValueCollection wsHeader, int localPort) : this(requestUrl, BackMessageType.Error, webSocket, wsHeader, ex, ipAddress, null, null, true)
112 117 {
118 LocalPort = localPort;
113 119 }
114 120
115 121 internal CyberCommServerEventArgs WithTransport(CyberCommWebSocketPeer peer) => this with
Modified XFEExtension.NetCore/CyberComm/CyberCommServerEventArgsImpl.cs +4 -4
@@ -6,7 +6,7 @@ namespace XFEExtension.NetCore.CyberComm;
6 6
7 7 record CyberCommServerEventArgsImpl : CyberCommServerEventArgs
8 8 {
9 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, string message, string ipAddress, NameValueCollection wsHeader, bool endOfMessage) : base(requestUrl, webSocket, message, ipAddress, wsHeader, endOfMessage) { }
10 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, byte[] bytes, string ipAddress, NameValueCollection wsHeader, bool endOfMessage) : base(requestUrl, webSocket, bytes, ipAddress, wsHeader, endOfMessage) { }
11 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, XFECyberCommException ex, string ipAddress, NameValueCollection wsHeader) : base(requestUrl, webSocket, ex, ipAddress, wsHeader) { }
12 }
9 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, string message, string ipAddress, NameValueCollection wsHeader, bool endOfMessage, int localPort) : base(requestUrl, webSocket, message, ipAddress, wsHeader, endOfMessage, localPort) { }
10 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, byte[] bytes, string ipAddress, NameValueCollection wsHeader, bool endOfMessage, int localPort) : base(requestUrl, webSocket, bytes, ipAddress, wsHeader, endOfMessage, localPort) { }
11 internal CyberCommServerEventArgsImpl(Uri? requestUrl, WebSocket webSocket, XFECyberCommException ex, string ipAddress, NameValueCollection wsHeader, int localPort) : base(requestUrl, webSocket, ex, ipAddress, wsHeader, localPort) { }
12 }
Modified XFEExtension.NetCore/XFEExtension.NetCore.csproj +3 -1
@@ -5,7 +5,7 @@
5 5 <ImplicitUsings>enable</ImplicitUsings>
6 6 <Nullable>enable</Nullable>
7 7 <GenerateDocumentationFile>True</GenerateDocumentationFile>
8 <Version>5.2.0</Version>
8 <Version>5.2.1</Version>
9 9 <Title>XFEExtension</Title>
10 10 <RepositoryUrl>https://github.com/XFEstudio/XFEExtension</RepositoryUrl>
11 11 <AnalysisLevel>latest</AnalysisLevel>
@@ -20,6 +20,8 @@
20 20 <PackageReleaseNotes>
21 21 ## 调整
22 22
23 CyberComm 请求上下文和 WebSocket 事件现在公开实际本地监听端口,支持 CDN/反向代理公开端口与回源端口不同的场景。
24
23 25 JSON 查询改为按访问路径惰性扫描;旧版 QueryableJsonNode 由兼容包装器提供,不再在字符串转换时构建完整节点树。
24 26
25 27 ## 新增