网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Buffers;
using System.IO.Pipelines;
using Dpz.Core.Service.V4.Services;
using Wangkanai.Detection.Services;

namespace Dpz.Core.Web.Library.Middleware;

public class HttpRequestRecord(RequestDelegate next, IDiagnosticContext diagnosticContext)
{
    public async Task InvokeAsync(
        HttpContext httpContext,
        IArticleService articleService,
        IConfiguration configuration,
        IDetectionService detectionService
    )
    {
        if (httpContext.Request.Path.Equals("/sitemap.xml", StringComparison.OrdinalIgnoreCase))
        {
            var host = configuration.GetSection("upyun")["Host"] ?? "https://localhost:37701";
            var baseUri = new Uri(host);
            var uri = new Uri(baseUri, "/sitemap/sitemap.xml");
            httpContext.Response.Redirect(uri.ToString());
            return;
        }

        SetDetection(detectionService);
        await EnrichFromRequestAsync(httpContext.Request);

        await next.Invoke(httpContext);
        var routeValues = httpContext.Request.RouteValues;
        if (
            routeValues["controller"] is "Article"
            && routeValues["action"] is "Read"
            && routeValues["id"] is string id
        )
        {
            await articleService.ViewAsync(id);
        }
    }

    private async Task EnrichFromRequestAsync(HttpRequest request)
    {
        if (request.Query is { Count: > 0 })
        {
            diagnosticContext.Set("QueryString", request.Query);
        }

        var bodyContent = await GetBodyContentAsync(request.BodyReader);
        if (bodyContent != string.Empty)
        {
            diagnosticContext.Set("RequestBody", bodyContent);
        }
    }

    /// <summary>
    /// 读取 http body
    /// 如果 body 超过 1 &lt;&lt; 10 字节,则不记录 body
    /// </summary>
    /// <param name="reader"></param>
    /// <returns></returns>
    private static async Task<string> GetBodyContentAsync(PipeReader reader)
    {
        var result = new StringBuilder();
        const long maxLength = 1 << 10;
        long totalLength = 0;

        while (true)
        {
            var readResult = await reader.ReadAsync();
            var buffer = readResult.Buffer;
            // 如果 buffer 长度已经大于等于 maxLength,直接截取并返回
            if (buffer.Length >= maxLength)
            {
                var span = buffer.Slice(0, maxLength);
                AppendString(result, span);
                result.Append("...");
                reader.AdvanceTo(buffer.Start, buffer.GetPosition(maxLength));
                //await reader.CompleteAsync();
                break;
            }

            totalLength += buffer.Length;

            if (readResult.IsCompleted && buffer.Length > 0)
            {
                AppendString(result, in buffer);
            }

            reader.AdvanceTo(buffer.Start, buffer.End);
            if (totalLength >= maxLength)
            {
                result.Append("...");
                break;
            }

            if (readResult.IsCompleted)
            {
                break;
            }
        }

        return result.ToString();
    }

    private static void AppendString(
        StringBuilder result,
        in ReadOnlySequence<byte> readOnlySequence
    )
    {
        var span = readOnlySequence.IsSingleSegment
            ? readOnlySequence.First.Span
            : readOnlySequence.ToArray().AsSpan();
        result.Append(Encoding.UTF8.GetString(span));
    }

    private void SetDetection(IDetectionService detectionService)
    {
        diagnosticContext.Set("Device", detectionService.Device.Type.ToString());
        diagnosticContext.Set("Browser", detectionService.Browser.Name.ToString());
        diagnosticContext.Set("BrowserVersion", detectionService.Browser.Version.ToString());
        diagnosticContext.Set("Platform", detectionService.Platform.Name.ToString());
        diagnosticContext.Set("Engine", detectionService.Engine.Name.ToString());
        diagnosticContext.Set("Crawler", detectionService.Crawler.Name.ToString());
        diagnosticContext.Set("UserAgent", detectionService.UserAgent.ToString());
    }
}
loading