Конференция "Сети" » Фильтрация Http заголовка и обеспечение целостности
 
  • Dima (12.04.08 21:14) [0]
    Добрый день.

    Ситуация такая: скачиваю файл по 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. И вообще, как посоветуете обеспечивать "одинаковость" файла с оригиналом на сервере? Просто у меня есть подозрение, что даже если я уберу этот заголовок, и получу ЧекСуммы файлов с сервера и скачанного, они будут разные. Как думаете?

    Спасибо
  • DVM © (12.04.08 23:52) [1]

    > 1. Как вы думаете, как лучше удалять этот заголовок?

    после заголовка два раза перевод строки: #13#10#13#10


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

    Все будет ок.
  • Dima (13.04.08 15:41) [2]
    Спасибо.
  • Dima (18.04.08 22:26) [3]
    Еще раз здравствуйте.
    К сожалению, не могу похвастаться, что все получилось...
    Скорее получилось именно то, чего я боялся. Файл скачивается неправильно :(

             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 пишу новый массив в файл

    Не работает :'(
  • Reindeer Moss Eater © (18.04.08 23:42) [4]
    какой ужас
  • Dima (19.04.08 09:32) [5]
    Да, к сожалению ужас. Я не просто так выложил данный пост.
    Дебажить н-ный раз скачивание файла побайтно это не просто так :(

    Я думал какой-нибудь профессиональный программист только окинув взглядом данный код увидит проблему... Ведь когда уже решал аналогичную задачу, все как на ладони...

    Может и нет.
  • DVM © (19.04.08 14:03) [6]

    > Dima

    Твой код никуда не годится. Если он каким-то чудом и будет где то работать, так это в стерильных условиях локальной сети. Да  и то неправильно будет работать.

    Объяснять долго почему. Не работают так с HTTP сервером. Ну хотя бы потому, что он заголовок в ответе не просто так сообщает, а для информации и дальнейшего использования.
  • DVM © (19.04.08 14:05) [7]

    > Dima

    Лучше возьми TIdHTTP или хотя бы WinInet Api используй. Зачем сразу в WinSock полез?
  • Anatoly Podgoretsky © (19.04.08 14:34) [8]
    Странно если бы получилось. То что после заголовка это далеко не файл, а то что указано в заголовке, который ты благополучно уничтожаешь. То что остается требуется еще обрабатывать в соответствии с заголовком.
    Как сказали не мучайся, пользуйся готовым компонентом.
  • Dima (19.04.08 16:55) [9]

    > Лучше возьми TIdHTTP или хотя бы WinInet Api используй.
    > Зачем сразу в WinSock полез?


    Да дело том, что я и переделываю програму с WinInet. В проге с WinInet все было шикарно и все "работало", но программа висла.
    Я вызывал URLDownloadToFile и все. Программа висит намертво...

    Читал про это в Интернете, говорят что это глюк в WinInet...
    Поэтому я отказался от WinInet..

    Я понял, что это все не так просто, поэтому может тогда посоветуете грамотную литературу на эту тему?
    Только не говорите искать в гугле, там я поищу тоже)))
  • FireMan_Alexey (19.04.08 17:12) [10]
    А ты 13101310 отличаеш от #13#10#13#10!
    Анализируй в ответе от сервера строку статус и длину передаваемых байт после заголовка, т.е.
    HTTP/1.* 200 OK
    ...
    Content-Length: ???

    200 или 2xx - все нормально!
    Content-Length: <длина файла после заголовка>
  • Anatoly Podgoretsky © (19.04.08 18:23) [11]
    > FireMan_Alexey  (19.04.2008 17:12:10)  [10]

    30x тоже нормально, например 302 File Moved - переадресация в другое место.
  • FireMan_Alexey (19.04.08 21:16) [12]
    Согласен :)
    Ему RFC бы почитать или накрайняк http://book.itep.ru
  • DVM © (19.04.08 22:01) [13]

    > Content-Length: <длина файла после заголовка>

    может этого заголовка и не быть. А Content-Type может быть multipart/x-mixed-replace и тогда будут приходить порции с разделителями и у каждой порции будет подзаголовок с Content-Length порции. Вообще говоря вариаций много и писать все самому с нуля это надо весь RFC читать.
  • Slym © (21.04.08 04:59) [14]
    Dima   (19.04.08 16:55) [9]
    В проге с WinInet все было шикарно и все "работало", но программа висла.

    против "висла" можно прикрутить отдельный поток (Thread)...
    если ты реализуешь полную поддержку RFC у тебя "виснуть" будет чаще и серьезнее :)
  • FireMan_Alexey (22.04.08 15:30) [15]
    Да у него в приеме нет анализа ошибки после recv поэтому сложно что-либо сказать, что он там получает!
    Читай про winsock и статусы ошибок при приеме/передаче.
 
Конференция "Сети" » Фильтрация Http заголовка и обеспечение целостности
Есть новые Нет новых   [134431   +14][b:0][p:0.002]