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