Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];

Вниз

Фильтрация Http заголовка и обеспечение целостности   Найти похожие ветки 

 
Dima   (2008-04-12 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 ©   (2008-04-12 23:52) [1]


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

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


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

Все будет ок.


 
Dima   (2008-04-13 15:41) [2]

Спасибо.


 
Dima   (2008-04-18 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 ©   (2008-04-18 23:42) [4]

какой ужас


 
Dima   (2008-04-19 09:32) [5]

Да, к сожалению ужас. Я не просто так выложил данный пост.
Дебажить н-ный раз скачивание файла побайтно это не просто так :(

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

Может и нет.


 
DVM ©   (2008-04-19 14:03) [6]


> Dima

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

Объяснять долго почему. Не работают так с HTTP сервером. Ну хотя бы потому, что он заголовок в ответе не просто так сообщает, а для информации и дальнейшего использования.


 
DVM ©   (2008-04-19 14:05) [7]


> Dima

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


 
Anatoly Podgoretsky ©   (2008-04-19 14:34) [8]

Странно если бы получилось. То что после заголовка это далеко не файл, а то что указано в заголовке, который ты благополучно уничтожаешь. То что остается требуется еще обрабатывать в соответствии с заголовком.
Как сказали не мучайся, пользуйся готовым компонентом.


 
Dima   (2008-04-19 16:55) [9]


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


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

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

Я понял, что это все не так просто, поэтому может тогда посоветуете грамотную литературу на эту тему?
Только не говорите искать в гугле, там я поищу тоже)))


 
FireMan_Alexey   (2008-04-19 17:12) [10]

А ты 13101310 отличаеш от #13#10#13#10!
Анализируй в ответе от сервера строку статус и длину передаваемых байт после заголовка, т.е.
HTTP/1.* 200 OK
...
Content-Length: ???

200 или 2xx - все нормально!
Content-Length: <длина файла после заголовка>


 
Anatoly Podgoretsky ©   (2008-04-19 18:23) [11]

> FireMan_Alexey  (19.04.2008 17:12:10)  [10]

30x тоже нормально, например 302 File Moved - переадресация в другое место.


 
FireMan_Alexey   (2008-04-19 21:16) [12]

Согласен :)
Ему RFC бы почитать или накрайняк http://book.itep.ru


 
DVM ©   (2008-04-19 22:01) [13]


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

может этого заголовка и не быть. А Content-Type может быть multipart/x-mixed-replace и тогда будут приходить порции с разделителями и у каждой порции будет подзаголовок с Content-Length порции. Вообще говоря вариаций много и писать все самому с нуля это надо весь RFC читать.


 
Slym ©   (2008-04-21 04:59) [14]

Dima   (19.04.08 16:55) [9]
В проге с WinInet все было шикарно и все "работало", но программа висла.

против "висла" можно прикрутить отдельный поток (Thread)...
если ты реализуешь полную поддержку RFC у тебя "виснуть" будет чаще и серьезнее :)


 
FireMan_Alexey   (2008-04-22 15:30) [15]

Да у него в приеме нет анализа ошибки после recv поэтому сложно что-либо сказать, что он там получает!
Читай про winsock и статусы ошибок при приеме/передаче.



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2009.10.25;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.054 c
2-1251465886
stas
2009-08-28 17:24
2009.10.25
Сообщение о успешной установке сервиса


15-1250969752
Gordom
2009-08-22 23:35
2009.10.25
Обновление Adobe Flash


3-1228583788
FUV
2008-12-06 20:16
2009.10.25
Индекс для вычисляемого поля


2-1251984161
LDV
2009-09-03 17:22
2009.10.25
TListBox - Color select item


15-1250858767
macrodens
2009-08-21 16:46
2009.10.25
Вопрос по RAID





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский