使用ssl和客户端证书(uploadReadAheadSize)上传大文件,但不希望提前读取所有数据



我试图搜索互联网/堆栈溢出,但找不到任何对我有效的相关答案。

我有一个asp.net web api2应用程序(仅使用ssl)。我试图允许上传大文件(最多36mb),但除非我将uploadReadAheadSize更改为提前读取此大小,否则我会从IIS收到一个错误,即请求太长。

我不想设置该属性,因为我的数据流只有在IIS读取完所有数据后才能到达。

我的问题是:如何使用ssl(!)和web api 2在不配置大型上传的情况下使用asp.net托管和进行大型文件上传因为我所采取的措施似乎都不够。

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)

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

C:WindowsSysWOW64>C:WindowsSystem32inetsrvappcmd 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"

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

...
<httpRuntime targetFramework="4.5.1" maxRequestLength="36864"  /> 
...

...
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="37748736"> 
...

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

[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 };          
}
}

属性和策略:

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);
}
}

我在请求中获得的内容

的确,我没有缓冲区,但由于预读,IIS仍然已经读取了该上下文之前的所有数据

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

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

HTH-

使IIS在初始握手期间需要SSL客户端证书。然后您的maxRequestLength="配置将生效。

相关内容

  • 没有找到相关文章

最新更新