在Kestrel与ASP.NET Core MVC中实现返回100 Continue的端点
问题:ASP.NET HttpPut端点未返回100 Continue响应
我创建了一个仅包含如下代码的[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 Continue响应。我尝试通过套接字分开发送请求,刚发送完请求头部分:
PUT /api/vector HTTP/1.1 Host: localhost Transfer-Encoding: chunked Expect: 100-continue
就收到了200响应,说明服务端并未等待后续请求内容。需要一个能生成100 Continue响应的端点来验证相关假设。
解决方案:生成100 Continue响应的端点实现
方式1:读取请求体触发自动处理
ASP.NET默认会在首次尝试读取请求体时,检查Expect: 100-continue头并返回100响应。只需在代码中读取请求体(哪怕是部分读取)即可触发该逻辑:
[HttpPut("api/vector")] public async Task<IActionResult> Put() { // 读取请求体片段,触发100 Continue响应 await Request.Body.ReadAsync(new byte[1], 0, 1); var bytes = System.Text.Encoding.ASCII.GetBytes("May your wisdom grace us until the stars rain down from the heavens."); Response.ContentType = "text/plain"; await Response.Body.WriteAsync(bytes, 0, bytes.Length); return Ok(); }
方式2:显式发送100 Continue响应
如果不需要读取请求体,也可以手动检查请求头并发送100响应:
[HttpPut("api/vector")] public async Task<IActionResult> Put() { // 检查请求头是否包含Expect:100-continue if (Request.Headers.TryGetValue("Expect", out var expectHeader) && expectHeader.Equals("100-continue", StringComparison.OrdinalIgnoreCase)) { // 发送100 Continue响应 Response.StatusCode = StatusCodes.Status100Continue; await Response.StartAsync(); } var bytes = System.Text.Encoding.ASCII.GetBytes("May your wisdom grace us until the stars rain down from the heavens."); Response.ContentType = "text/plain"; await Response.Body.WriteAsync(bytes, 0, bytes.Length); return Ok(); }
原理说明
ASP.NET的默认逻辑是:只有当代码尝试读取请求体时,才会处理Expect:100-continue头并返回100响应。如果端点直接返回响应而不触碰请求体,服务器会直接发送200响应,跳过100 Continue的步骤——这就是你遇到问题的核心原因。
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

