【问题标题】:ASP.NET Core disable Request Buffering (not response buffering)ASP.NET Core 禁用请求缓冲(不是响应缓冲)
【发布时间】:2020-12-03 08:55:57
【问题描述】:

我找到了控制响应缓冲的好方法。但我需要禁用 REQUEST 缓冲。

短版问题:

我发现后台有一个缓冲区,里面填满了请求数据。断点请求方法不会暂停此过程,因此它显然是由后台线程完成的。我遵循了一些说明(例如关闭 FormValueProviderFactory),但它们并没有阻止这种行为。

长版问题:

我已经实现了代码here

该示例创建了一个名为 DisableFormValueModelBindingAttribute 的过滤器属性,文档声称该属性可防止将文件加载到内存中,但它没有此效果。过滤器在请求开始流式传输后被命中。

但我发现整个请求仍然缓冲到内存中。它达到请求内存限制并开始存储在磁盘中,但这会导致服务器耗尽磁盘空间。由于该服务托管在 docker 中,因此我只有几百 MB 可用。我真正需要的是仅将多部分请求缓冲到我可以读取它的位置

我正在使用 .net core 2.1 和 AspNetCore 2.1.1

关于 Request.EnableBuffering 的说明

名称不正确 - 请求总是被缓冲,这实际上是启用请求回退。

关于 IHttpBufferingFeature.DisableBuffering 的说明

这是过时的。它没有实现细节。过时的标签说

[Obsolete("See IHttpRequestBodyFeature or IHttpResponseBodyFeature DisableBuffering", error: true)]

但是 IHttpRequestBodyFeature doesn't exist.

令人失望,因为当这个答案出现时我很兴奋!

更多信息

经过一些实验,我已经弄清楚了一些事情。我将请求从控制器移到中间件中。

app.Use ((context, next) =>
{

    var Request = context.Request;

    if (MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
    {
        // a breakpoint here doesn't stop the upload
        var path = Request.Path;

// ...

但我发现有一个后台线程正在填充请求缓冲区。我在中间件中设置了一个断点,但我仍然可以看到后台发生的上传。请求缓冲区仍在填充。

答案可能与可以对 HttpRequestFeature 进行的可能配置有关。

更多信息

在 UseKestrel 的回调中,您可以配置限制并且有限制

称为“MaxRequestBufferSize”

但默认情况下这是 1MB。很明显,它不负责将完整请求缓冲到磁盘。

我还发现a github issue 关于缓冲是可配置的,主要是抱怨它不是。这让我没有信心。

【问题讨论】:

    标签: .net asp.net-core out-of-memory


    【解决方案1】:

    在撰写本文时,这是不可能的。

    IHttpRequestBodyFeature 未实现或公开,因此我们无法调用方法来禁用请求缓冲。只有一种方法可以在 IHttpResponseBodyFeature 中使用 DisableBuffering 方法禁用响应缓冲。

    我在 GitHub 上搜索了IHttpRequestBodyFeature 的最少结果 https://github.com/search?q=IHttpRequestBodyFeature&type= 进一步支持该接口尚不可用或向我们公开的想法。另一方面,如果您搜索 IHttpResponseBodyFeature,您会从 dotnet 和 aptnetcore 获得大量结果。

    我建议为IHttpRequestBodyFeature 在此处不可用的问题提交问题: https://github.com/dotnet/aspnetcore/issues

    我找不到在IHttpResponseFeature 中禁用请求缓冲的方法。没有提供method 这样做。然而IHttpResponseBodyFeature 有一个method 来禁用响应缓冲;下面是一个例子:

    1. 添加以下命名空间

      using Microsoft.AspNetCore.Http.Features;

    2. IActionResults 中您希望禁用 响应缓冲,使用 DisableBuffering()方法:

    选择退出响应的写入缓冲

    var bufferingFeature2 = HttpContext.Features.Get<IHttpResponseBodyFeature>();
    bufferingFeature2?.DisableBuffering();
    

    【讨论】:

    • @gburton 我修改了答案你可以试试吗?
    • 当你第一次回答时我真的很兴奋,因为我认为你已经找到了一个简单的解决方案。但是 DisableBuffering 不再存在。接口 IHttpBufferingFeature 已过时(error=true,因此如果使用它,您甚至无法编译)并将您定向到不再存在的 API。您给出的报价是 WRT 响应,而不是请求。你付出了很多努力,我真的很感激,但遗憾的是答案不正确。
    • 我刚才注意到修改后的答案引用了 response 缓冲区。所以它可能会起作用,但它是对不同问题的回答!我仍然很欣赏你所做的工作。希望我能接受答案并给你多汁的赏金。
    • 您的回答似乎是正确的。遗憾的是我们实际上无法控制这个缓冲区,所以我将不得不编写一个 OWIN 中间件。从历史上看,大文件上传并没有很好地集成到 asp.net 中,而且在 AspnetCore 中似乎也不是一个重要的考虑因素。
    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    相关资源
    最近更新 更多