从Web API控制器重定向POST请求时,处理100-继续

Jor*_*ins 5 c# asp.net iis http-status-code-100 asp.net-web-api2

我有一个ApiController响应POST请求,通过HTTP的状态码307重定向它.它只使用标题中的信息,因此此操作不需要请求的主体.此操作相当于:

public HttpResponseMessage Post() {
    var url;
    // Some logic to construct the URL
    var response = new HttpResponseMessage(HttpStatusCode.TemporaryRedirect);
    response.Headers.Location = new System.Uri(url);
    return response;
}
Run Code Online (Sandbox Code Playgroud)

这很简单,但我想做一个改进.请求正文可能包含大量数据,因此我想利用HTTP状态代码100来提高此请求的效率.使用现在的控制器,对话可能如下所示:

> POST /api/test HTTP/1.1
> Expect: 100-continue
> ...

< HTTP/1.1 100 Continue

> (request body is sent)

< HTTP/1.1 307 Temporary Redirect
< Location: (the URL)
< ...
Run Code Online (Sandbox Code Playgroud)

由于重定向操作不需要请求主体,我希望能够将会话缩短为:

> POST /api/controller HTTP/1.1
> Expect: 100-continue
> ...

< HTTP/1.1 307 Temporary Redirect
< Location: (the URL)
< ...
Run Code Online (Sandbox Code Playgroud)

我花了一天的时间来研究如何实现这一目标,但我还没有找到解决方案.在我的研究中,我学到了:

  • ApiController执行动作时,100 Continue已经发送了.
  • ApiController构建时,100 Continue已发送.
  • HttpApplicationPreRequestHandlerExecute触发事件时,100 Continue反应尚未发送.
  • DelegatingHandler执行时,100 Continue已发送.

基于此,我到目前为止提出的最佳解决方案是创建一个HttpModule使用RouteDataon RequestContext来覆盖响应,当ApiController问题是请求的接收者时.这远非理想的解决方案,然而,由于若干原因(码分离,没有利用网络API的参数的结合,并且在一个绕过附加逻辑AuthorizeAttributeApiController).

似乎必须有一个更好的解决方案,但我发现很少有关于如何正确处理Expect: 100-continueWeb API应用程序中的标头的信息.实现此操作ApiController以正确处理Expect: 100-continue标头的最简单方法是什么?

K. *_*tes 1

...您确定需要此优化吗?

如果您使用的是 IIS 6,则需要进入 IIS 5 兼容模式并编写 ReadRawData/SendRawData ISAPI 筛选器。由于我的回复中进一步给出的原因,ISAPI 扩展是不可能的。(如果您使用的是 IIS 5 或更低版本,愿上帝怜悯您的灵魂)

如果您使用的是 IIS 7+,您也许可以不必编写 IIS 本机模块。

您的想法是正确的,当控制器参与时,响应已经发送,因为 Web API 存在于 ASP.NET 中;此响应由 IIS 核心处理。

一些轻读材料

HTTP.SYS IIS 和 100 继续

王大卫

“100 continue”与“400 Bad Request”或内核响应缓存命中一样,其特殊之处在于 HTTP.SYS 在内核模式下透明地处理它,而不通知用户模式任何内容。此外,ISAPI 扩展无法与任何响应交互输出 - 他们只能生成响应输出,看不到响应输出的结果。因此,ISAPI 扩展将永远无法与生成“100 continue”或“100 continue”响应的请求交互以抑制它们。

在 IIS6 上,将用户模式处理注入到 HTTP.SYS 的这些透明请求处理中的唯一方法是在 IIS5 兼容模式下运行并使用 ReadRawData/SendRawData ISAPI 筛选器。ReadRawData 强制 HTTP.SYS 将原始数据从网络传递到用户模式,以便在将用户模式输出解析为 HTTP 请求并放入队列之前进行过滤。

当然,这种方法完全违背了运行具有应用程序池和进程隔离的 IIS6 的目的(此过滤用户模式进程中的单个故障会导致整个服务器停止运行)...但这就是当客户端有错误时服务器端的妥协。 ..

仅供参考:此方法不适用于 Vista Server/IIS7。HTTP.SYS 将不再将网络上的原始数据在解析之前传递到用户模式进行过滤,因此用户模式代码不可能知道触发自动“100 continue”的请求发生了。


编辑

被黑客攻击的 Http Web 请求期望 100 继续