ASP.NET 4.0中防止上传大文件

17
我们想要限制网站上传文件的最大大小。我们已经在web.config中设置了适当的限制。我们遇到的问题是,如果上传一个非常大的文件(例如1 GB),则会在生成服务器端错误之前上传整个文件,而且文件是否巨大会导致不同类型的错误。
是否有一种方法可以在实际上传之前检测挂起文件上传的大小?
这是我的相关web.config设置,用于限制请求大小为16 MB:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="12288"/>
    </system.web>

    <system.webServer>
        <security>
            <requestFiltering>
                <requestLimits maxAllowedContentLength="12582912"/>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

我尝试创建一个HTTP模块,以便在请求生命周期的早期拦截请求,但似乎上传甚至发生在HttpApplicationBeginRequest事件之前:

我尝试创建一个HTTP模块,在请求生命周期的早期拦截请求,但似乎上传甚至发生在HttpApplicationBeginRequest事件之前。

public class UploadModule : IHttpModule
{
    private const int MaxUploadSize = 12582912;

    public void Init(HttpApplication context)
    {
        context.BeginRequest += handleBeginRequest;
    }

    public void Dispose()
    {
    }

    private void handleBeginRequest(object sender, EventArgs e)
    {
        // The upload takes place before this method gets called.

        var app = sender as HttpApplication;

        if (app.Request.Files.OfType<HttpPostedFile>()
            .Any(f => f.ContentLength > MaxUploadSize))
        {
            app.Response.StatusCode = 413;
            app.Response.StatusDescription = "Request Entity Too Large";
            app.Response.End();
            app.CompleteRequest();
        }
    }
}

更新:

我知道像Flash这样的客户端技术可以在上传之前检测文件大小,但我们需要一个服务器端的解决方案,因为我们想要针对没有Flash/Java/ActiveX/Silverlight支持的平台。我相信IIS或ASP.NET存在一个bug,允许上传大文件而不受限制,所以我在这里提交了一个bug here

与HTTP模块和处理程序相比,ISAPI扩展是否可以给我更多的请求处理控制权,例如允许我在看到Content-Length头超过允许的限制时中止上传?

更新2:

,微软已将我提交的错误标记为重复,但未提供任何其他信息。希望他们没有忘记这件事。

更新3:

太好了!据微软称:

该错误正在解决,因为它已转移到IIS产品团队。IIS团队已经修复了这个错误,并将包含在未来的Windows版本中。


对这个问题点赞,我自己也对这个话题很感兴趣。我的理解是,在整个请求到达之前,你无法对其进行任何操作,而且你正在尝试使用的代码肯定没有预先知道的方法。我认为需要在请求管道中更早地处理;例如在客户端或在IIS/ASP.NET收到请求之前 - 当请求开始流入时。 - Andrew Barber
也许你可以参考这个链接:https://dev59.com/bmzXa4cB1Zd3GeqPUH6m#14033087 - Colin Niu
4个回答

3

微软已在其Microsoft Connect网站上回应如下:

该漏洞正在得到解决,因为它已被移植到IIS产品团队。 IIS团队已经修复了该漏洞,并将包含在Windows的未来版本中。

如果您要请求当前操作系统的修复程序,则必须打开QFE请求。请告诉我是否要采取此路线。请注意,打开QFE请求并不一定意味着它会被批准。

所以我想我们必须等待下一个IIS版本的修复(除非QFE请求得到满足,不知道那是什么)。


3
有没有办法在实际上传之前检测待上传文件的大小?
不行。这需要在客户端访问文件大小。允许Web服务器直接访问客户端上的文件可能有点危险。
最好的方法是放置一行文本,说明允许的最大文件大小。
或者您可以创建某种ActiveX控件、Java小程序等,以便不受浏览器限制。然后您需要说服用户安装它。这可能不是最佳解决方案。

1
正确。但是在服务器端上传整个文件之前,应该有一种方法来检测上传的文件大小:我们可以在接收和解析请求头之后立即读取“Content-Length”标头(但在整个请求被处理之前)。我稍后会更新这个内容。 - Colin Niu
请参考以下链接:https://dev59.com/bmzXa4cB1Zd3GeqPUH6m#14033087 - Colin Niu

3
问题在于上传是使用HTTP Post请求一次性完成的,因此只能在上传完成后检测到它。如果您想更好地控制上传过程,可以尝试基于Flash的上传小部件,它具有更多功能。请查看此链接:http://www.ajaxline.com/10-most-interesting-upload-widgets

1
你让它听起来像是HTTP的一个根本限制,但实际上这是Web服务器软件的限制。 - Charlie

1

嗯...这取决于你想要多底层。

创建一个服务应用程序,充当IIS的代理。 (所有传入的80端口套接字请求都转到服务。)让服务将其接收到的所有内容传递给IIS(在不同端口或IP上侦听的网站),但监视其接收到的总请求大小。 当来自给定连接的大小超过所需限制时,关闭连接。如果您想礼貌地返回重定向到错误页面。

虽然有些愚蠢,但它可以让您监视传输中的数据,而无需等待IIS交付请求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接