-
Здравствуйте! Столкнулся со следующей проблемой:
Занимаюсь разработкой сайта на ISAPI, столкнулся с проблемами ограничения загружаемого контента. То есть например хочу получить файл от пользователя, делаю сделующее:
var
SL: TStringList;
MS: TMemoryStream;
FileName: string;
FileSize: Integer;
begin
try
MS := TMemoryStream.Create;
SL := TStringList.Create;
FileSize := TMemoryStream(Request.Files.Items[0].Stream).Size;
SL.Add('Files count: ' + IntToStr(Request.Files.Count) + '<br>');
SL.Add('Files name: ' + ExtractFileName(Request.Files.Items[0].FileName) + '<br>');
SL.Add('Files SIZE: ' + IntToStr(FileSize) + '<br>');
SL.Add('File saved to: C:\Inetpub\wwwroot\' + ExtractFileName(Request.Files.Items[0].FileName) + '<br><br>');
Response.Content := Response.Content + SL.Text;
MS.LoadFromStream(Request.Files.Items[0].Stream);
MS.SaveToFile('C:\Inetpub\wwwroot\' + ExtractFileName(Request.Files.Items[0].FileName));
SL.Free;
MS.Free;
except
on E: Exception do
Response.Content := 'Error desc - ' + E.Message;
end;
end;
Все загружается, все нормально. Но при попытке проверить длинну загружаемого контента и если он(контент) больше положенного размера выдать сообщение об ошибке пользователю все время выскакивает:
Internet Explorer не может отобразить эту веб-страницу
Возможные причины:
Нет подключения к Интернету.
На веб-узле возникли неполадки.
Возможно, сделана опечатка в адресе.
Длинну проверяю просто, это вставляю перед try в вышеизложенном листинге:if Request.ContentLength > 20000 then
begin
Response.SendRedirect('http://' + Request.Host + '/Error.htm');
exit;
end;
И еще вопрос, сам процесс загрузки файла на сервер, то есть, как я понимаю сначало весь контент передается на сервер только потом начинает работать ISAPI с этим контентом? Или я ошибаюсь? Возможно ли сразу проверить размер загружаемого контента не дожидаясь его загрузки на сервер? -
piople © (14.08.08 5:09)
MS.LoadFromStream(Request.Files.Items[0].Stream);
"Нафега ты фсякую дрянь ташешь?" (SHOC)
куча уязвимостей! такой сервер завалить с полпинка:
1)DOS посылкой файла с одинаковым именем приведет:
1. к одновременному доступу к одному файлу на запись...
2. что приведет к неосвобождению SL и MS в одном из потоков
3. при более менее продолжительной атаке сервер исчерпает всю память и грохнется.
2)Если не посылать файл то:
1. Request.Files.Items[0] вызовет исключение
2. что приведет к неосвобождению SL и MSvar
SL:TStringList;
FileName: string;
begin
try
SL:=TStringList.Create;
try
SL.Add('Files count: ' + IntToStr(Request.Files.Count) + '<br>');
for i:=0 to Request.Files.Count-1 do
with Request.Files.Items[i] do
begin
SL.Add('File name: ' + ExtractFileName(FileName) + '<br>');
SL.Add('File size: ' + IntToStr(Stream.Size) + '<br>');
FileName:='C:\Inetpub\wwwroot\' + ExtractFileName(FileName);
try
with TFileStream.Create(FileName, fmCreate) do
try
LoadFromStream(Stream);
finally
Free;
end;
SL.Add('File saved to: '+FileName + '<br><br>');
except
on E: Exception do
SL.Add('Can''t saved file to: '+FileName+' Error desc - ' + E.Message + '<br><br>');
end;
end;
Response.Content := Response.Content + SL.Text;
finally
SL.Free;
end;
except
on E: Exception do
Response.Content := 'Error desc - ' + E.Message;
end;
end; -
Ващу девизию, я что написал? Я спрашивал про уязвимость кода? Или что? Я задал конкретный вопрос, как сделать проверку размера файла и выдать сообщение пользователю о размере файла, ВСЕ!
А тот код что я привел это не более чем пробник, появилась необходимость загружать файлы на сервер я ей занялся... столкнулся с проблемой задал вопрос, в вашем коде что-то решения проблемы я не вижу...
З.Ы. Стримы всеравно в БД буду писать, на винт созраняется только для отладки удобства отладки... -
piople © (14.08.08 5:09)
сначало весь контент передается на сервер
проверить несложно :) пошли файлик побольше и выведи в лог время начала процедуры, время до обращения к потоку (.Size), время после обращения к потоку, время после сохранения потока в файл... -
piople © (15.08.08 4:21) [2]
не более чем пробник
таких пробников на рабочих серверах нимало забыто... а потом бегают "Пачему сервер упал?" -
> сначало весь контент передается на сервер
> проверить несложно :) пошли файлик побольше и выведи в лог
> время начала процедуры, время до обращения к потоку (.Size),
> время после обращения к потоку, время после сохранения
> потока в файл...
В этом взя и проблема, я же писал выше... Если сразу проверить рамер контента и если он больше нежного сделать Response.Content := 'Ахтунг слижкам бальшой файл0!', вываливается ошибка о том что данный адресс недоступен. -
чисто теоретически все верно...
Клиент должен начать прием данных только после полной отправки запроса... а твой сервер невыкачав запроса уже ответ дает -
rfc2616(HTTP).txt
[Page 32]
The presence of a message-body in a request is signaled by the
inclusion of a Content-Length or Transfer-Encoding header field in
the request's message-headers. A message-body MUST NOT be included in
a request if the specification of the request method (section 5.1.1)
does not allow sending an entity-body in requests. A server SHOULD
read and forward a message-body on any request; if the request method
does not include defined semantics for an entity-body, then the
message-body SHOULD be ignored when handling the request. -
имя(12.11.08 04:18) [8]Удалено модератором