Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Фильтрация 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


> Как думаете?

Все будет ок.


Наверх

Титульная страница Поиск, карта сайта Написать письмо