Предотвращение загрузки больших файлов в ASP.NET 4.0
Мы хотели бы ограничить максимальный размер загружаемого файла на нашем веб-сайте. Мы уже установили соответствующие ограничения в нашем web.config. Проблема, с которой мы сталкиваемся, заключается в том, что если загружен действительно большой файл (например, 1 ГБ), весь файл загружается до того, как будет сгенерирована ошибка на стороне сервера, и тип ошибки будет разным, независимо от размера файла или не.
Есть ли способ определить размер ожидающей загрузки файла до того, как будет произведена фактическая загрузка?
Вот мои соответствующие настройки web.config, которые ограничивают запросы до 16 МБ:
<?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, чтобы я мог перехватить запрос в начале жизненного цикла запроса, но загрузка, похоже, происходит еще до BeginRequest
событие HttpApplication
:
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 есть ошибка, которая позволяет загружать большие файлы, несмотря на ограничения, поэтому я подал ошибку здесь.
Может ли расширение ISAPI дать мне больший контроль над обработкой запросов, чем модули и обработчики HTTP, например, позволяя мне прервать загрузку, если заголовок Content-Length окажется больше допустимого предела?
Обновление 2:
Вздох Microsoft закрыла ошибку, которую я подал как дубликат, но не предоставила никакой дополнительной информации. Надеюсь, они не просто бросили мяч на этом.
Обновление 3:
Ура! По словам Microsoft:
Эта ошибка устраняется, поскольку она была перенесена в группу разработчиков продуктов IIS. С тех пор команда IIS исправила ошибку, которая будет включена в будущий выпуск Windows.
4 ответа
Microsoft ответила на их сайте Microsoft Connect следующим:
Эта ошибка устраняется, поскольку она была перенесена в группу разработчиков продуктов IIS. С тех пор команда IIS исправила ошибку, которая будет включена в будущий выпуск Windows.
Если вы запрашиваете исправление для текущей ОС, должен быть открыт запрос QFE. Пожалуйста, дайте мне знать, если это тот маршрут, по которому вы хотите идти. Обратите внимание, что открытие запроса QFE не обязательно означает, что он будет одобрен.
Поэтому, я думаю, нам нужно дождаться следующей версии IIS для исправления (если не выполнен запрос QFE, что бы это ни было).
Есть ли способ определить размер ожидающей загрузки файла до того, как будет произведена фактическая загрузка?
Нет. Это потребует доступа к размеру файла на клиенте. Разрешение веб-серверу прямого доступа к файлам на клиенте было бы немного опасно.
Лучше всего разместить строку текста с указанием максимально допустимого размера файла.
ИЛИ вы можете создать какой-то элемент управления ActiveX, Java-апплет и т. Д., Чтобы вы не зависели от ограничений браузера. Затем вы должны убедить своих пользователей установить его. Наверное, не лучшее решение.
Проблема заключается в том, что загрузка происходит одновременно с использованием HTTP Post-запроса, поэтому вы можете обнаружить его только после того, как он сделан.
Если вы хотите больше контроля над этим, вы должны попробовать Flash-загрузку виджетов, которые имеют это и многое другое. Проверьте эту ссылку http://www.ajaxline.com/10-most-interesting-upload-widgets
Ну.... Зависит от того, как низкоуровневый вы хотите получить.
Создайте приложение-службу, которое действует как прокси для IIS. (Все входящие запросы сокетов порта 80 направляются в службу.) Попросите службу передать все, что она получает, в IIS (веб-сайт прослушивает другой порт или IP-адрес), но следите за общим размером запроса по мере его поступления. Когда размер данного соединения превышает желаемый предел, закройте соединение. Верните перенаправление на страницу с ошибкой, если вы хотите быть вежливым.
Глупо, но это позволит вам отслеживать данные в пути, не дожидаясь, пока IIS передаст запрос.