![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Фильтрация Http заголовка и обеспечение целостности
Dima © (2008-04-12 21:14:00)Добрый день.
Ситуация такая: скачиваю файл по http вот так:
function download (ServerName,File: string):boolean;
var
s: TSocket;
Data: TWSAData;
Addr: TSockAddr;
Recived: Integer;
BtBuff: array [0..1023] of Byte;
HTTPRequest: string;
F: File;
begin
WSAStartup($101, data);
s:=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
Addr.sin_family:=AF_Inet;
Addr.sin_port:=htons(80);
Addr.sin_addr.S_addr:=inet_addr(PAnsiChar(ServerName));
if (connect(s,Addr,SizeOf(TSockAddr)) <> SOCKET_ERROR) then
begin
HTTPRequest:='GET '+File+' HTTP/1.1'+#13#10+'Host: '+ServerName+#13#10+'Connection: Close'+#13#10#13#10;
send(s, HTTPRequest[1], length(HTTPRequest),0);
Recived:= 1;
AssignFile(F,File);
Rewrite(F, 1);
while Recived <> 0 do
begin
Recived:= recv(s,BtBuff,Length(BtBuff),0);
BlockWrite(F,BtBuff,Recived);
end;
CloseFile(F);
closesocket(s);
Result:= True;
end;
WSACleanup();
end;
Но проблема в том, что если открыть скачанный файл в текстовом редакторе, то в начале есть:
HTTP/1.1 200 OK
Date: Sat, 12 Apr 2008 16:42:10 GMT
Server: Apache/2.2.6 (Win32) PHP/5.2.3
Last-Modified: Sat, 12 Apr 2008 16:12:24 GMT
ETag: "32fe-1f0-50f3172c"
Accept-Ranges: bytes
Content-Length: 496
Connection: close
Content-Type: application/zip
Вопросы:
1. Как вы думаете, как лучше удалять этот заголовок?
2. И вообще, как посоветуете обеспечивать "одинаковость" файла с оригиналом на сервере? Просто у меня есть подозрение, что даже если я уберу этот заголовок, и получу ЧекСуммы файлов с сервера и скачанного, они будут разные. Как думаете?
Спасибо
FireMan_Alexey (2008-04-22 15:30:00) [1]Да у него в приеме нет анализа ошибки после recvпоэтому сложно что-либо сказать, что он там получает!
Читай про winsock и статусы ошибок при приеме/передаче.
Slym (2008-04-21 04:59:00) [2]Dima (19.04.08 16:55) [9]
В проге с WinInet все было шикарно и все "работало", но программа висла.
против "висла" можно прикрутить отдельный поток (Thread)...
если ты реализуешь полную поддержку RFC у тебя "виснуть" будет чаще и серьезнее :)
DVM (2008-04-19 22:01:00) [3]
> Content-Length: <длина файла после заголовка>
может этого заголовка и не быть. А Content-Type может быть multipart/x-mixed-replace и тогда будут приходить порции с разделителями и у каждой порции будет подзаголовок с Content-Length порции. Вообще говоря вариаций много и писать все самому с нуля это надо весь RFC читать.
FireMan_Alexey (2008-04-19 21:16:00) [4]Согласен :)
Ему RFC бы почитать или накрайняк http://book.itep.ru
Anatoly Podgoretsky (2008-04-19 18:23:00) [5]> FireMan_Alexey (19.04.2008 17:12:10) [10]
30x тоже нормально, например 302 File Moved - переадресация в другое место.
FireMan_Alexey (2008-04-19 17:12:00) [6]А ты 13101310 отличаеш от #13#10#13#10!
Анализируй в ответе от сервера строку статус и длину передаваемых байт после заголовка, т.е.
HTTP/1.* 200 OK
...
Content-Length: ???
200 или 2xx - все нормально!
Content-Length: <длина файла после заголовка>
Dima (2008-04-19 16:55:00) [7]
> Лучше возьми TIdHTTP или хотя бы WinInet Api используй.
> Зачем сразу в WinSock полез?
Да дело том, что я и переделываю програму с WinInet. В проге с WinInet все было шикарно и все "работало", но программа висла.
Я вызывал URLDownloadToFile и все. Программа висит намертво...
Читал про это в Интернете, говорят что это глюк в WinInet...
Поэтому я отказался от WinInet..
Я понял, что это все не так просто, поэтому может тогда посоветуете грамотную литературу на эту тему?
Только не говорите искать в гугле, там я поищу тоже)))
Anatoly Podgoretsky (2008-04-19 14:34:00) [8]Странно если бы получилось. То что после заголовка это далеко не файл, а то что указано в заголовке, который ты благополучно уничтожаешь. То что остается требуется еще обрабатывать в соответствии с заголовком.
Как сказали не мучайся, пользуйся готовым компонентом.
DVM (2008-04-19 14:05:00) [9]
> Dima
Лучше возьми TIdHTTP или хотя бы WinInet Api используй. Зачем сразу в WinSock полез?
DVM (2008-04-19 14:03:00) [10]
> Dima
Твой код никуда не годится. Если он каким-то чудом и будет где то работать, так это в стерильных условиях локальной сети. Да и то неправильно будет работать.
Объяснять долго почему. Не работают так с HTTP сервером. Ну хотя бы потому, что он заголовок в ответе не просто так сообщает, а для информации и дальнейшего использования.
Dima (2008-04-19 09:32:00) [11]Да, к сожалению ужас. Я не просто так выложил данный пост.
Дебажить н-ный раз скачивание файла побайтно это не просто так :(
Я думал какой-нибудь профессиональный программист только окинув взглядом данный код увидит проблему... Ведь когда уже решал аналогичную задачу, все как на ладони...
Может и нет.
Reindeer Moss Eater (2008-04-18 23:42:00) [12]какой ужас
Dima (2008-04-18 22:26:00) [13]Еще раз здравствуйте.
К сожалению, не могу похвастаться, что все получилось...
Скорее получилось именно то, чего я боялся. Файл скачивается неправильно :(
HTTPRequest:='GET '+PathToFile+' HTTP/1.1'+#13#10+'Host: '+ServerName+#13#10+'Connection: Close'+#13#10#13#10;
send(s, HTTPRequest[1], Length(HTTPRequest),0);
Flag:= 0;
Recived:= 1;
while Recived <> 0 do
begin
Recived:= recv(s,BtBuff,Length(BtBuff), 0);
if Flag = 0 then
begin
for i:=0 to Length(BtBuff)-1 do
if ((BtBuff[i] = 13) AND (BtBuff[i+1] = 10)) then
if ((BtBuff[i+2] = 13) AND (BtBuff[i+3] = 10)) then
break;
ii:= i + 4;
for i:= ii to Length(BtBuff)-1 do
begin
SetLength(BtBuffTmp,Flag+1);
BtBuffTmp[Flag]:= BtBuff[i];
inc(Flag);
end;
BlockWrite(F,BtBuffTmp,Length(BtBuffTmp));
Flag:= 1;
end
else
BlockWrite(F,BtBuff,Recived);
end;
CloseFile(F);
closesocket(s);
Суть в следующем:
1. Начинаем скачивать файл.
2. Так как заголовок http попадет только в 1й массив байт, то для 1го прохода один вариант обработка, а для второго и других - просто пишем в файл.
3. 1й проход обрабатываю так:
3.1 ищу в массиве 13101310 и запоминаю номер следующего элемента.
3.2 начиная с номера запомненного элемента пишу в новый массив
3.3 пишу новый массив в файл
Не работает :'(
Dima (2008-04-13 15:41:00) [14]Спасибо.
DVM (2008-04-12 23:52:00) [15]
> 1. Как вы думаете, как лучше удалять этот заголовок?
после заголовка два раза перевод строки: #13#10#13#10
> Как думаете?
Все будет ок.