namespace Dpz.Core.WebApi.Middleware;

/// <summary>
/// 处理HTTP响应中间件
/// </summary>
public class HttpResponseHeaderHandel
{
    private readonly RequestDelegate _next;

    /// <summary>
    ///
    /// </summary>
    /// <param name="next"></param>
    public HttpResponseHeaderHandel(RequestDelegate next)
    {
        _next = next;
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    public async Task Invoke(HttpContext httpContext)
    {
        /*
         * from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
         * 列出哪些 http response headers 对外暴露
         * 这里设置为所有
         */
        httpContext.Response.Headers.Append("Access-Control-Expose-Headers", "*");
        if (
            httpContext.Request.Path.Equals("/swagger", StringComparison.OrdinalIgnoreCase)
            || httpContext.Request.Path.Equals(
                "/swagger/index.html",
                StringComparison.OrdinalIgnoreCase
            )
        )
        {
            httpContext.Response.Redirect("/scalar/v1", true);
            return;
        }

        // if (
        //     string.Equals(
        //         httpContext.Request.Query["format"],
        //         "xml",
        //         StringComparison.OrdinalIgnoreCase
        //     )
        // )
        // {
        //     httpContext.Response.ContentType = "application/xml";
        // }
        if (
            string.Equals(
                httpContext.Request.Query["format"],
                "msgpack",
                StringComparison.OrdinalIgnoreCase
            )
        )
        {
            httpContext.Response.ContentType = "application/x-msgpack";
        }

        await _next.Invoke(httpContext);

        if (httpContext.Response.StatusCode == 401)
        {
            httpContext.Response.Headers.WWWAuthenticate =
                "Bearer realm=\"api\" error=\"invalid_token\"";
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个ASP.NET Core的自定义HTTP中间件类,名为HttpResponseHeaderHandel,主要用于处理HTTP响应的头部信息和一些特殊逻辑。让我详细解释一下这个中间件的功能:

主要功能

1. CORS响应头处理

httpContext.Response.Headers.Append("Access-Control-Expose-Headers", "*");
  • 设置CORS(跨域资源共享)响应头
  • Access-Control-Expose-Headers: * 表示允许前端JavaScript访问所有的响应头
  • 这对于需要在前端获取自定义响应头的场景很有用

2. Swagger重定向

if (httpContext.Request.Path.Equals("/swagger", StringComparison.OrdinalIgnoreCase) ||
    httpContext.Request.Path.Equals("/swagger/index.html", StringComparison.OrdinalIgnoreCase))
{
    httpContext.Response.Redirect("/scalar/v1", true);
    return;
}
  • 当用户访问 /swagger/swagger/index.html
  • 自动重定向到 /scalar/v1
  • 这表明项目可能使用了Scalar作为API文档工具,而不是默认的Swagger UI

3. 内容类型处理

if (string.Equals(httpContext.Request.Query["format"], "msgpack", StringComparison.OrdinalIgnoreCase))
{
    httpContext.Response.ContentType = "application/x-msgpack";
}
  • 检查请求查询参数中的format参数
  • 如果值为"msgpack",则设置响应内容类型为MessagePack格式
  • 注释掉的XML部分表明之前可能也支持XML格式输出

4. 401状态码处理

if (httpContext.Response.StatusCode == 401)
{
    httpContext.Response.Headers.WWWAuthenticate = "Bearer realm=\"api\" error=\"invalid_token\"";
}
  • 在请求处理完成后检查响应状态码
  • 如果是401(未授权),则添加WWW-Authenticate
  • 指示客户端使用Bearer token进行身份验证

中间件模式

这个类遵循标准的ASP.NET Core中间件模式:

  • 构造函数接收下一个中间件的委托
  • Invoke方法处理请求和响应
  • 使用await _next.Invoke(httpContext)调用管道中的下一个中间件

使用建议

要使用这个中间件,需要在Program.csStartup.cs中注册:

app.UseMiddleware<HttpResponseHeaderHandel>();

这个中间件适合放在认证中间件之后,但在控制器处理之前的位置。

评论加载中...