在 Kestrel 和 ASP.NET Core MVC 中实现返回 100 Continue HTTP 状态的端点

问题描述 投票:0回答:1

我创建了一个

[HttpPut]
控制器端点,其中仅包含

var bytes = System.Text.Encoding.ASCII.GetBytes("May your wisdom grace us until the stars rain down from the heavens.");

Response.ContentType = "text/plain";
Response.Body.Write(bytes, 0, bytes.Length);

我向它发送了请求:

PUT /api/vector HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
Expect: 100-continue

12
0123456789ABCDEF

0

我收到回复:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/plain
Server: Microsoft-IIS/10.0
X-SourceFiles: =?UTF-8?B?RDpcZGV2XGZvcm1idWlsZGVyXHNyY1xDZWRhcm9uLkZvcm1CdWlsZGVyLldlYkFQSVxhcGlcdmVjdG9y?=
X-Powered-By: ASP.NET
Date: Mon, 14 Oct 2024 20:33:05 GMT

May your wisdom grace us until the stars rain down from the heavens.

没有 100 继续回复???

所以我再次尝试将插座连接到键盘(这样我就可以设置暂停)。一旦我提供了

PUT /api/vector HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
Expect: 100-continue

我收到了回复,所以它绝对不会先查看是否发送了额外的东西。

我有一些假设,我想检查大约 100 个继续,但如果我没有生成 100 个继续的工作端点,我无法检查它。

asp.net-core-mvc http-status-code-100
1个回答
0
投票

经过测试,似乎可以通过使用自定义中间件开始工作。这是测试结果。

enter image description here

继续Middleware.cs

using System.Reflection.Metadata;

namespace ContinueTestApi
{
    public class ContinueMiddleware
    {
        private readonly RequestDelegate _next;

        public ContinueMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (context.Request.Headers.ContainsKey("Expect") &&
                context.Request.Headers["Expect"].ToString().Equals("100-continue", StringComparison.OrdinalIgnoreCase))
            {
                //Kestrel automatically handles 100 Continue, so there is no need to set it manually.
            }

            context.Response.OnStarting(() =>
            {
                if (!context.Response.HasStarted)
                {
                    context.Response.ContentType = "text/plain";
                }
                return Task.CompletedTask;
            });

            await _next(context);
        }
    }
}

注册

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseMiddleware<ContinueMiddleware>();

app.UseAuthorization();

app.MapControllers();

app.Run();

我的测试代码

using Microsoft.AspNetCore.Mvc;

namespace ContinueTestApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class TestController : ControllerBase
    {

        private readonly ILogger<TestController> _logger;

        public TestController(ILogger<TestController> logger)
        {
            _logger = logger;
        }

        [HttpPut]
        public async Task<IActionResult> Put()
        {
            using (var reader = new StreamReader(Request.Body))
            {
                var body = await reader.ReadToEndAsync();
            }

            var responseMessage = "May your wisdom grace us until the stars rain down from the heavens.";
            var bytes = System.Text.Encoding.ASCII.GetBytes(responseMessage);

            Response.ContentType = "text/plain";
            await Response.Body.WriteAsync(bytes, 0, bytes.Length);

            return new EmptyResult();
        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.