使用ssl和客户端证书(uploadReadAheadSize)但不希望所有数据都是预读的大文件上传

use*_*260 7 .net asp.net iis asp.net-mvc-5 asp.net-web-api2

我试图搜索互联网/堆栈溢出,找不到任何适合我的相关答案.

我有一个asp.net web api2应用程序(仅使用ssl).我正在尝试允许大文件上传(最多~36mb)但除非我更改uploadReadAheadSize以预读此大小我从IIS收到错误请求太长.

我不想设置该属性,因为那时我的数据流只在IIS读完之后到达.

我的问题是:如何在没有配置大型uploadreadaheadsize的情况下使用 asp.net托管并使用ssl(!)和web api 2 进行大文件上传?因为看起来我采取的所有步骤都是不够的.

应将UploadReadAheadSize:

指定Web服务器将读入缓冲区并传递给ISAPI扩展或模块的字节数.每个客户端请求发生一次.ISAPI扩展或模块直接从客户端接收任何其他数据.该值必须介于0和2147483647之间.默认值为49152.

如果我没有设置uploadReadAheadSize并尝试通过ssl上传大文件,这是我得到的错误:

HTTP错误413.0 - 请求实体太大

您可以尝试的事项:页面未显示,因为请求实体太大.

最可能的原因:

Web服务器拒绝为请求提供服务,因为请求实体太大.Web服务器无法为请求提供服务,因为它正在尝试协商客户端证书,但请求实体太大.请求URL或到URL的物理映射(即URL的内容的物理文件系统路径)太长.您可以尝试的事项:验证请求是否有效.如果使用客户端证书,请尝试:

增加system.webServer/serverRuntime@uploadReadAheadSize

配置SSL端点以在初始SSL握手过程中协商客户端证书.(netsh http add sslcert ... clientcertnegotiation = enable)

Verify that the request is valid.
  If using client certificates, try:
    Increasing system.webServer/serverRuntime@uploadReadAheadSize
    Configure your SSL endpoint to negotiate client certificates as part of the initial SSL handshake. (netsh http add sslcert ... clientcertnegotiation=enable)
Run Code Online (Sandbox Code Playgroud)

如果我将预读配置为我想允许的大小,iis允许我的请求:

C:\Windows\SysWOW64>C:\Windows\System32\inetsrv\appcmd set config ... -section:system.webServer/serverRuntime /uploadReadAheadSize:n /commit:apphost
Applied configuration changes to section "system.webServer/serverRuntime" for "MACHINE/WEBROOT/APPHOST/..." at configuration commit path "MACHINE/WEBROOT/APPHOST"
Run Code Online (Sandbox Code Playgroud)

我在web.config中配置了这个:

...
<httpRuntime targetFramework="4.5.1" maxRequestLength="36864"  /> 
...
Run Code Online (Sandbox Code Playgroud)

...
<system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="37748736"> 
...
Run Code Online (Sandbox Code Playgroud)

我有一个接收文件的虚拟控制器

[ControllerBufferlessAttribute()]
public class UploadController : ApiController
{
    public HttpResponseMessage Post([FromUri]string filename)
    {
        var selector = RequestContext.Configuration.Services.GetHostBufferPolicySelector();
            var isbufferless = string.Format("It is {0} that i'm bufferless but still IIS already read all the data before this context because of the readahead", selector is PolicySelectorBufferless);
            return new HttpResponseMessage(HttpStatusCode.InternalServerError) { ReasonPhrase = isbufferless };          
    }
}
Run Code Online (Sandbox Code Playgroud)

属性和政策:

public class ControllerBufferlessAttribute : Attribute, IControllerConfiguration
{
    public void Initialize(HttpControllerSettings settings,
        HttpControllerDescriptor descriptor)
    {
        settings.Services.Replace(typeof(IHostBufferPolicySelector), new PolicySelectorBufferless());
    }
}
public class PolicySelectorBufferless : WebHostBufferPolicySelector
{
    public override bool UseBufferedInputStream(object hostContext)
    {
        return false;
    }
    public override bool UseBufferedOutputStream(HttpResponseMessage response)
    {
        return base.UseBufferedOutputStream(response);
    }
}
Run Code Online (Sandbox Code Playgroud)

我在请求中收到的内容

这是真的,我是无缓冲的,但由于readahead,IIS仍然已经在此上下文之前读取了所有数据

lju*_*mir 0

为了使用 requestLimits 功能,您需要首先在 IIS 级别上进行设置

也许您一开始就忘记在 IIS 服务器上安装请求过滤。

华泰