Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Распаковка gzip ответа Http сервера на лету c++ Builder6 / 17 сообщений из 17, страница 1 из 1
05.07.2014, 17:33
    #38688642
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
День добрый.
Долго гуглил, но результата особо никакого, благодаря архивы gzip - распаковка сжатого файла распаковка файла при помощи zlib получилась, но интересует не файл переданный в функцию, а ответ сервера например в виде TMemoryStream .
Нашел решение но на Delphi Используем GZip в Synapse . Там есть модуль в котором описаны функции как раз решающие мою задачу.
Меня временно бы устроило если бы сервер всегда слал не сжатые данные. Но почему-то не получается сказать серверу что мне нужны не сжатые данные. Тестировал программу на разных ПК, с каких-то ответ приходит сжатый, с каких-то нет, с чем связано не понятно.
Кто сталкивался с подобными задачами что можете посоветовать?
...
Рейтинг: 0 / 0
05.07.2014, 17:41
    #38688644
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Кстати пробовал ещё функцию описанную здесь приспособить, для своих нужд, но безрезультатно, хотя ошибок никаких не возникало, на выходе 0.
...
Рейтинг: 0 / 0
05.07.2014, 18:04
    #38688649
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
yura-007распаковка файла при помощи zlib получилась
Вообще-то zlib работает с буферами в памяти. Как ты ей умудрился скормить файл - непонятно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.07.2014, 18:36
    #38688652
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Я видимо плохо понимаю как это работает, но:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
const int KILOB = 1024;
char cb[KILOB];
AnsiString arch = "C:\\111.xml.gz";
FILE* outfile = fopen("C:\\newfile.xml", "wb");
gzFile gfile = gzopen (arch.c_str(), "rb");
int len = 0;
do
{
len = gzread (gfile, cb, KILOB);
if(len < KILOB) cb[len]=0;
fprintf(outfile, "%s" , cb);
} while(len == KILOB);
fclose(outfile);
gzclose(gfile);



len = gzread ( gfile , cb, KILOB);

тогда как в это gzFile gfile загрузить не файл, а буфер в памяти?
...
Рейтинг: 0 / 0
05.07.2014, 18:40
    #38688653
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
yura-007тогда как в это gzFile gfile загрузить не файл, а буфер в памяти?
В одном клике от тобой же приведённой главной страницы zlib находится и
подробно расписанный пример и
полная документация .
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
06.07.2014, 01:09
    #38688747
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Спасибо, пример действительно пригодился, не заметил.
В общем после долгих танцев с бубном, слепил функцию, она конечно далека от идеала, т.к. я практически полный NULL в Builder'е, но тем не менее делает почти то что требуется:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
#define CHUNK 16384
void StreamUncompress(TMemoryStream *StmDesc, TMemoryStream *StmGzip)
{
  char buf[CHUNK];
  int r=0;

  int fdpipe[2];
  if( _pipe( fdpipe, StmGzip->Size, O_BINARY ) == -1 ) return;

  while( ( r = StmGzip->Read(buf,sizeof(buf))) > 0 ) _write( fdpipe[1], buf, r);
  close(fdpipe[1]);

  AnsiString compressedBytes = AnsiString(buf);
  AnsiString uncompressedBytes = "";

  unsigned full_length = sizeof(buf) ;
  unsigned half_length = full_length / 2;

  unsigned uncompLength = full_length ;
  char* uncomp = (char*) calloc( sizeof(char), uncompLength );

  z_stream strm;
  strm.next_in = (Bytef *) buf;
  strm.avail_in = full_length ;
  strm.total_out = CHUNK;
  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;

  bool done = false ;

  if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK)
  {
    free( uncomp );
    return;
  }

  while (!done) {
    // If our output buffer is too small
    if (strm.total_out >= uncompLength )
    {
      // Increase size of output buffer
      char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
      memcpy( uncomp2, uncomp, uncompLength );
      uncompLength += half_length ;
      free( uncomp );
      uncomp = uncomp2 ;
    }

    strm.next_out = (Bytef *) (uncomp + strm.total_out);
    strm.avail_out = uncompLength - strm.total_out;

    // Inflate another chunk.
    int err = inflate (&strm, Z_SYNC_FLUSH);
    if (err == Z_STREAM_END) done = true;
    else if (err != Z_OK)
    {
      break;
    }
  }

  if (inflateEnd (&strm) != Z_OK)
  {
    free( uncomp );
    return;
  }

  for ( size_t i=0; i<strm.total_out; ++i )
  {
    uncompressedBytes += uncomp[ i ];
  }

  char buf2[CHUNK];
  AnsiString str = "String";
  strcpy(buf2, uncompressedBytes.c_str());

  r = StmDesc->Write(buf2,sizeof(buf2));
  free( uncomp );
}


тестирую так, сторонним архиватором сделал архив README.gz и:
Код: plaintext
1.
2.
3.
4.
5.
    TMemoryStream *mstrSrc = new TMemoryStream;
    mstrSrc->LoadFromFile("README.gz");
    TMemoryStream *mstrDesc = new TMemoryStream;
    StreamUncompress(mstrDesc,mstrSrc);
    mstrDesc->SaveToFile("README.txt");



Но задача разархивировать ответ от сервера и тут скорей всего тоже не все так просто, если я правильно понимаю нужно будет извлечь именно сжатую часть, удалив заголовок и TMemoryStream'ом передать в функцию.

Любые комментарии, замечания, баги в функции приветствуются!
...
Рейтинг: 0 / 0
06.07.2014, 06:32
    #38688770
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Ответ http-сервера упакован, если это указано в заголовке Content-Encoding.
...
Рейтинг: 0 / 0
06.07.2014, 18:38
    #38688901
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Basil A. Sidorov,

Может я что-то делал не так, пробовал разные варианты, сейчас данный участок кода выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
         IdHTTP1->ProtocolVersion = pv1_0 ;
      // IdHTTP1->Request->AcceptLanguage = "ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3";
      // IdHTTP1->Request->AcceptEncoding = "gzip";
      // IdHTTP1->Request->ContentEncoding = "gzip";
      // IdHTTP1->Response->ContentEncoding = "gzip";
       IdHTTP1->Request->Accept = "*/*";
      // printf(IdHTTP1->Request->ContentEncoding.c_str());
       IdHTTP1->Post(controllerIP, s, fs)

       if (IdHTTP1->Response->ContentEncoding == "gzip")
       {


Протокол поставил 1.0, вычитал что с ним тоже сжиматься не должно, но тем не менее на одном ПК не сжимается, на другом сжимается. Нужно будет снифером проверить отличаются ли заголовки.
Когда я такую же программу писал на С#, то там у меня получилось сказать серверу вот так:
Код: c#
1.
2.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriString);
                request.AutomaticDecompression = DecompressionMethods.None;


Даже если получится заставить сервер слать не запакованный ответ, это временное решение пока не научусь распаковывать.
...
Рейтинг: 0 / 0
07.07.2014, 09:41
    #38689104
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Basil A. Sidorov,

Заголовок запроса на ПК с Win7 32-bit:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
POST /html/xml.cgi HTTP/1.0
Host: 11.111.11.11
Accept: */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
Content-Type: application/x-www-form-urlencoded
Content-Length: 8417

<cmd version="C" lang="eng" action="read_val"...


команды в целях экономии места обрезал. Вот заголовок на другом ПК с Win XP 32-bit:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
POST /html/xml.cgi HTTP/1.0
Host: 11.111.11.11
Accept: */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
Content-Type: application/x-www-form-urlencoded
Content-Length: 8615

<cmd version="C" lang="eng" action="read_val"... 


не смотря на то что Content-Length немного отличается, внешне один в один.
А вот ответы от одного и того же сервера на этот запрос ПК Win7 32-bit:
Код: xml
1.
2.
3.
4.
5.
HTTP/1.0 200 OK
Server: KwikNet Web Server
Content-Length: 25645

<?xml version="1.0" encoding="utf-8"?><resp version="C" ...


Win XP 32-bit:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
HTTP/1.0 200 OK
Server: KwikNet Web Server
Content-Encoding: gzip
Content-Length: 2849

‹     яНќСrЫ¶†_Ј{+$eКтLмЋЖn¦™&с™Иsn;ЄHЩj%RCQIуVзО“u—Й],U(%:7mю*ж§°Шс§пъkіVЯвl·J“»Ѓ?ф*NiґJ^оы|y5ьtя>‹wЫжSµћгЏ“—Ѓљ/твПfс<ънЫ|=PЙ~у[љ¬АПЁ}ІКwwѓьЬ,Kі»Ѓ7ёSIЕщЏmџГџЃЯЭ
‚ЃZ¬"ьЊъ†яф=ш·hµЫ®зрУ®®®ФГ>Oч9|~ѕЃПSe—Пу»БSІ^%с@бпаk?у^бЇ`иэяпЯБіm а+Ф ™з«ЗХrgq’ЇЉЇZ`Hэ4Lис!0Ѓъ<яK-XD2Џ«ЗAФ6NКaОі}<(‚4тЬ‚4b\#хy•.®Zq]щЋ\ЧЊлo·ЄiфЗPэZНЎМУu+6ҐЩBЖЄзxівjiА&#152;hNе)ЫYоујЕнw№љНWYѓЈЙж@Еъs“CГдг䆹µыѕКЇ5™.'»ч­c°ЃтGкЛке5Wйr№‹›±ъq†¶…з8‰BљіС­z~кdљjОеЩОўђеКkЏРђе&tsў1ЏШcкФ‰ЫF9Љ0„ї/ю¬&’ФЏіЭ[‡Зу<љї§ЮHMЧуlЈў¶·ЉAИяЂPДCЌјН*±+ЂЎk~ЉI0Mі'Шђ§ЎСхг8­уZЌЭиь	Ї),рямЧл(эОй„nKwлHwЛиFкИ	џV5mтеR“нШ‚·­ШhN&#152;ъЧкSъ] qХЉмКµHр6¦Б
Lяб#О}хшRGYТM…nEKВq=ЊЭиF=¤ITlКАYУ	ЭЋ.tЪпZO__cH]jЋщЈbГмЕds4Ы\Іє|e1T|Cх”Ё|µЃк»J©›•©M9,ПРЈЫРлa`{Z.56]їЫ€о ‹‘§6[•kаґU‡ё	ЭњНv$}ЏХ~8‡геPНтyVW7єzЗiW$№4Вџї‰уЧ4Є""дгъ.d_рylE0Ѓђh–§[М
’®›3“{мљЯYёFЬЗ$Џ3hl8]·„SjтљЩЧґ¤€ ¤АюѓGі‚ФmЩ®C§‚‡6ѓ‘Ѕ¤*<'xy6qУd[4—„‡ґЕ€ј±zМV[=cIэBptл‰јхaћМ0;АЦЭДM“/„F›ГИ›Фh|ЎкєЬUиёPi=y·чёПа`
VD8]7‡sЙlґnЌ|'&¶YњмљE ts&ыЈ^ЇFю“Жуkњ}Э'П„IЧН™ЄRВ!Ўґ”€ьЫГсг,„S@В¦лvlЃcMРZ·и_Тu4]ВN@&&#152;ФНбмk‰Н‡Є!KwщNcлІPкgDв•к(/`BЦO·кб©Z…B¶ І>O
YгэК$‚ћ{И€4ЩњЁљо{dИ6ў°Ѓ№b•“КGкvpn=ђ°І,Ї
EѕпkV/F©ЫББOумEаУD‘ы‡"Ш`6ЎЫі9ЊjАЋќтC=«=pe=Ыицp.ЃЈI,‡у,‘ЃNЧнЩњGлЩОл
ё‘8]·‡s	cѓі¦ЉЌNЧнЩњGkнПqTЇхАйє=њKањЏUl<pєnПж8Ъ	дР¤pЎ8]·‡s	cу8]·gs
­<rlЎpЖЌхАйє=њKа›Я0рАйє=›}аx@ОТbW…Щ§еУ>ЯЦ;—Ф­бzvЂЈЫjЉ;ЧGПe—«¦gІ9љu·5Н)М3lќТ¬dЄкI©›3¶%lпla~A…Ѕ pФHєlNk~G±ЃТ©џ^ЏХГ|«Е:ћ'5™¦љѓ9Я„ољйЌ§fбa>Х8\<+ЌGП/°-ъщЧ<yеЅЏУЬЫ#њРУЂэш¶xЭ_”ъхВЧХ АIвЯ}—{-¬|ЮГY	¶
УЋSи§їАt5vмЇYЩјЗCH>шиэ®љ,єjfЫ[б€NЭ}}Я ЯR5aТеs±wRы`RЮ`Ѓ·НС€®љгаlВ+[ЦЩ0јЎ)§8k(пЏ)r—EИv`юd8ІџжAиУDЅ'ђz6[яЭ§OіяЦ3JSНБ|ЛгzАЎЅЧ~\њЛ·Q5Ћ¦љгШOpћВв`TЈбў9Њ}l®iеQҐжџсcM4‡±ЋФhtвT.оSк4с8Ќх:,х`|}~(ЇsТЗ±гЗУyЉЯЇҐЙзSµc љzЂ°есµЦсГiЕ‰ЗK%*Љwя\п‚ц~—JЪ&#152;Ь1‚Илp_IЮЂА[L•Ъ1Ђ^­a= FЃ€?ћѕOВ!(v~	АдЋhБ€Хы]ЪiHЅ[¶‰VУЫ©wЎgDЩЧ U;91џ'Сп?Ф.ЅУ¬<cz·"-~V.†@ег-µ;”Ђ“лРc•ЋГSЕЩ—ІеўЄЦd|{тн+з\^lТfI :iҐgЎј|$хгЎ©ЊБйbXВР	¬»*”еe

<’”ъўpgюџ;ц2&#152;Ѕю’\ґђћ…*bplН<ЗЇu№µК’ЌV^­№њ—AА°ыlњфеeђdґЂИtУВauщш ћц2‚7дelЅz$
Л•Віp,Ў­—ЫеЅ"<РТь-Le|„|<<еVbtw»
ґ:iчлehЎ{C^†6:ZФУВa /бehaco6ъу2ґ‘СnLza»€—Ў…о
ytєЮЅ:ї!&=еPJэx.kMхpЇифлYЙF·Ў~Ѕ‚­w/ѓNti/ѓ|>;§¦…r&	Щ|"№фњtхлeh	­!ўГэЄ^ј-l Х%…ф,Tc©{МіxГҐLј-pґмУЛР‚F{AйYЁв—]&#152;ЗБ6n.ЩЊф№O/CKЬhsШЇ—ЎЋV;зр2њ|ПЫВDлЦ^ј’‰Х«ЅzZШШNР«—A‡ѓ+Lt'АЫK{t$ЯлЭЛ ђxҐ*LejІyfµ_„oЗЛР,єIПB-Эг`.ЬАsЯђ—Aо-y$;vкХЛ ЩШ}љ~ЅЋ№Ћzх2H6vdџчкeђp­µ{х2H6v9пХЛ б&#152;™¬W/ѓdуйжђчкeђp¬KйХЛ Щрпк«ЫвјW/ѓч¦ј-pґю¦…ІІy5b]јЅ/ѓЊл RЭґp€’.›G©<t1с2Hґ~Ѕ’§O/ѓ¤№Ё—A<ю^† 4№д­“А4]з{@9\jЃМHыkЭµP®*]5_T§.4л1кЭЛ ЃОоeА+[§.ІI¬x`FьЅёЌ]Гјґ—Ў‡MpНµp&#152;аљzО	О“ ·-hёhsКЛ cУЈ—AА\ЦЛРцxљћс¤‘ШК‘СДг#sТJСцx:OсIФµР<џЄ T]А µoЃ<ѕЦ:~8нҐсбЬіР pЅcЪы!3-4LоЃvQ€@]
U; o›
ЂуyЪV}џ„Џg¦…& Lо8фх"њЭЛР¶‰Vgх2ґAи‘єИXзv·CБОM1
3жYhёЮ-„H‹Фґ@Ё|њ х
ђЃ—A«$08ФµРpQХ‹zЮбяибюobеєb  



Content-Encoding в запросе отсутствует, тем не менее сервер разным клиентам отвечает по разному.
Передав в ранее опубликованную мной здесь функцию сжатый ответ, ничего расшифровать не получилось, капаю дальше.
...
Рейтинг: 0 / 0
07.07.2014, 10:52
    #38689166
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Прошу прощение, ранее был не точен, на С# что бы все работало нужно написать так:
Код: c#
1.
2.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriString);
                request.AutomaticDecompression =  DecompressionMethods.GZip | DecompressionMethods.Deflate;


В результате ответ от сервера все равно приходит запакованный(в снифере), зависит от ПК пославшего запрос, AutomaticDecompression распаковывает и уже в нормальном виде с ответом можно работать.
...
Рейтинг: 0 / 0
07.07.2014, 15:55
    #38689569
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Капнув глубже в спецификацию gzip , стало понятно что ничего не понятно.
Чтоб хоть как-то понять структуру архива создал текстовый документ "1.txt", следующего содержания: "1", сжал его в gzip и посмотрел на полученный файл "1.gzip" в far manager'е (скрин прикрепил) [img=Структура gzipJPG.JPG]
Если я правильно все понял, то благодаря спецификации, со структурой данного файла разобрался.
Далее создал текстовый файл который заполнил сжатым ответом сервера, переименовал расширение на gz , в результате архив открывается 7зипом в таблице отображается 1 файл:
Код: xml
1.
2.
3.
4.
5.
6.
Имя: 2
Размер: 538 980 792
Сжатый: 2 357
Изменен: 1987-01-30 07:38
Система: Unknown
CRC: EACB9E24


но при извлечении файла получаю ошибку "Ошибка в данных. Файл 2 испорчен".
Подозреваю что CRC EACB9E24 и Размер не корректны. Хотя заголовок у данного архива в far'е похож на заголовок из спецификации.
Собственно сжатое содержимое с которым экспериментировал:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
‹     яН[koЪHэ+#‡ъЃ	HM«,ЩЁU›f•D[н§ИЕ&с.ШИШyьы=wЖ3¶‡1``ЙцK
±=gОЅчЬ‡'?ї.жм9КVqљњ[NЯ¶X”LУ0NП­"џхFЦзOіhµ¬®љXlРпЈдСbБ4зчfQ>,ѓlс'іФbaфOЈ‡8<·мСа·Сpм<ШЋчj±¤X<¤Йь
лaµ,K3\b}ъH7ЇШ4-’ьЬще7,°Ф*К—iњдёЈHbь>Њ§›тЗ[м™~:6Р'Б":·zЅ›yZд[ДШc¬зЫґЅEрК?2с1ЊfA1Зqc.]с&#152;ҐЕтЬrо•~ъѕЕІ—sл§Ет·%ћ~h­А¬Н¦б$ ђ2Ыa—сleQ’ЗБјЖ&#152;ЭЗe
&#152;Лq&#152;Ѓ*мNвrЩuрК¦:]ѓс6єѓ{Уe@еUЁ<v'лЁ4#
ђu®J3пЌКdДAk #®–}vюЭgЯ*#ц„Х6‘Ыµ3°р-y&#152;З«ьAШл>Z,№ЗЙHXs9ё«4­Пит>…L	UF N±¶оуш¦бс?wчx§fГ1СT¬rvДYЌ+§‰вЈ‚Г#с(\]pЎ»—8џ>µ±ењ)¶
Ь°*oаВС“‘Y'Њѕ,ниK™8Ђ2·І&#152;г±сгSОТЩљчњЭМfn’6є|lіt.oМоџъM ш-ЏЂ:YшNуyќЄЯvч.O.ЧШµхЎЁi„Iичs/‘zфЂsбҐa>ШоЧфџѓbОМ
њR_Я¶mҐж¶З.жHM€оyрVщ•ґ0wЂЏН&#152;c^e+яей?wђ3,%6t3Mі›e”ІЋё†ЗЕеЊ¤Б.ууy&#152;ѕмѓkј.^ОуЕГS_ЮTМ8г
¦Зѕ@ѕЗvСPТ\}T«i”U·5
з<Э‚УВя/њыћѕмізХ#ІLA СэЬКМоўўI!Б.їb?\Ыyь§aa®RЅ
&#152;wЖ&iт,
€u`Н9чбЌx¶—yFиT®j*вЪѓ†ЊЭFђ0ђ”” °АmW&Гe
ЅШUЖьЄzџўTѕЋ“>»IX/ў:+љ№ёd5X:WІ‚Вн уm•o¦6КЂB~<(­рЫ&#152;&#152;}OҐЂ©gі	jДЊ{ыtkЬЩ7›ЇЌ(Эz\Ач*ЁлСAч'…‚еe4лі»<Иd•і!j$Ј)u„$¬’±л(JС›™у7т§ДR“Fёе
к@1¶.ЪElѕф±6`m5іЎн©ј,„—Ђ»<]’(Ф]ї)®Oє®рp-Ц¤^ВЪ®ф‚•'иz;­|*DYA°ѕ&y”=7›W="P·&,ЖрХ^lЃюuTК‹BTФєІ-:бЊЦИbPt<T€ ‘C]T‹!FыujT™J0*ТЋ
;” †м2‹—»ЁU[єЏЉJ%љР>cWAВE ЙyUм&#152; МYY5‚Ў=RЁљ1ШsxР©&ѓќ«їBіацФTлGъбЇhХ.XЄЂн1aЅ,2LмљШ¦X(<>K©™Џ’U
µhSSU¶†ЋM±IZFчИP eњБ:ё}эЛ ZU9:#Т‡ы§(»-’{№ѕ©мc&ХЪ‚З0	tU):гr:yзc$ШАҐ‰ьєѓ‰9Sg3Лµ]%с”’ї¤урb‰_ч$Jц2чmзEOКЖХЫSJPд_Pѓ\–|ТUvZэVОgхХ5?Ю\µ:ф
Х ‚Bћ.ЩдF‹-3&8ї±L1W†ьжЫ*ї]Ў хС0ч«хЌоKќ»ІOuEй&Э@™дС·U*№BЦеў
RтF‰ІГ„ЅСіHXЫе±­Dq«К)—Ґ›ѓн?eЌ Тт.sAq;[pКГLи:*Фs§,(Ѓ
ЖЮ€КЗBµ®‹€uYдe‘ЙЬяU*Мb.©цЄч¦J…`^ѕМыPUЎВ&#152;&#152;STпM•Є{sљс‘эЗ§j«s+П
$М%rюzR|Їдv–WЧ© cZ%ї7‹J]st”|;SUЎr*TЗ¦Єѓ=MЄ¦J€ЬF‹Cю7<>suялМb…Р©›ЕnЁЬЪМ#剓ћЩM‘/7ҐЁ!MJBY‚fъ')ЛZѕSжФ
2>‘5–€А©RiJYл«CуТY¬ъjU!љЛ±}!mмqPu(IбuвbЃK+Б€вP»%HЃЇhS$s<Mґц)ј
]Хо4v(Ы4_щ&#152;љhzЋЦLа›ЖWЧVНz“`±Й<
 ІЕ€ѕ
Ѓt0dь†©ё[ЈГ›ВЅMи—®Т
k¤jzfі»къcўвУи9Xbd™ююmBCPкxZИіХ`‚љ¤Ъх
”ьр‹ЙХґjц\wM¦|Л,
©ЬGњ	 †6БхGЁa…[Г1нП{„JTpNўСв–rњУ)ї’±"7 єlAЁќ~G§·БД$Z©JЃ
,O·њ¤=§ъ`RтIГИ№Q±Тd¦Eь$ueD+вф™—Р№щфN(}ORЎ0Рk-ЙЁp3Ll±ћ5ZQљгГЇЮ[оHњwБ»ЏЪTE:”Ыmu9	ЁоqЖ*EwА
Ѓq¦$ђЏ:p†€ЮEЦЏЕ¦90Z&#152;ЈwvҐsщ#€%‚ыГчпwож\°yЭlкtњо\m‹ѓe©|LШo¬Nіxя> ћpнЃZ[кщпtr·}ГbuТ;Ж
Є>er№8?Ђ№Ыв(z[ј±уЫы‰8эyўЕ•їСОй@ЪIWW
ЙWчOє¶*Vim:GВт~‡7ы›]µ‘ґ>О‡њxщ¦твR—c
л›7f‚ЭDбЧ(ж(џџТ굂'и“.ЇjCZ-oЧk=Лж2Ѓz®ѓд§Jwr}­gъЇЧoИ_k„«T5DІ^ЯэAЋH]•HїD:ђ$ьхЖi(ИОdlm+vЌ‘¦Tѕфе_”y‚w¶ЋљdAЗяЁX«®ђдµxЋЮЩљK•Z·@\Эda”эHЎcu@НWcь«™±jЖ[ЌYГЗяЮ`…ї; їЕшф/$ћЛкё1  


В общем не понятно на правильном ли я пути, но капаю дальше.
Подсказки приветствуются!
...
Рейтинг: 0 / 0
07.07.2014, 22:35
    #38689852
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Тип компрессора (gzip или deflate) указан в заголовке серверного ответа.
Поэтому:
1. По заголовку серверного ответа выбираем распаковщик;
2. Если выбранный распаковщик вернул ошибку - реально битые данные.
...
Рейтинг: 0 / 0
08.07.2014, 09:29
    #38690041
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Basil A. SidorovТип компрессора (gzip или deflate) указан в заголовке серверного ответа.
Поэтому:
1. По заголовку серверного ответа выбираем распаковщик;
Так и делаю, условие отрабатывает как положено:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
       if (IdHTTP1->Response->ContentEncoding == "gzip")
       {
          try
          {
             TMemoryStream *mstrDesc = new TMemoryStream;
             StreamUncompress(mstrDesc,fs);
             mstrDesc->SaveToFile("README.txt");
             fs->SaveToFile("README_2.txt");
             fs = mstrDesc;
             AnsiString ch = IntToStr(fs->Size) + "  ";
             printf(ch.c_str());
          } 
          catch(Exception &e)
          {
             printf(e.Message.c_str());
          }
       }


но README.txt забивается в основном пробелами, т.к. в функции его размер задан константой. Пока не знаю как его сделать динамическим.
Basil A. Sidorov2. Если выбранный распаковщик вернул ошибку - реально битые данные.
Не исключено, т.к. я ковырял данные взятые из снифера копи пастом, хотя программа принявшая данные (на с# написанная) с ними отработала корректно.
Сейчас попробую файл README_2.txt ковырнуть. И никогда раньше не пользовался, но наверняка есть программы для восстановления битых архивов, попробую найти такую и скормить ей ответ сервера, интересно что получится.
...
Рейтинг: 0 / 0
08.07.2014, 10:16
    #38690083
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
Аллилуйя! Переименовав README_2.txt в README_2.gz, архиватор открыл архив и без ошибок извлекся файл без расширения README_2, открыв который блокнотом я увидел нормальный ответ http сервера. Осталось допилить функцию. Ситуация осложнена тем что на ПК, которому сервер отвечает архивом, не установлен Builder, приходится всячески извращаться.
...
Рейтинг: 0 / 0
08.07.2014, 11:44
    #38690197
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
yura-007не установлен Builder, приходится всячески извращаться.чего там извращаться? собери комплект dll и bpl, необходимых твоей программе и подложи их рядом с exe. Делов то.
...
Рейтинг: 0 / 0
08.07.2014, 12:46
    #38690306
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
egorychyura-007не установлен Builder, приходится всячески извращаться.чего там извращаться? собери комплект dll и bpl, необходимых твоей программе и подложи их рядом с exe. Делов то.
Расшифровать gzip тоже делов то, когда знаешь. А когда в данной среде работаешь пару недель, не понятно...
Хорошо бы ссылку!
...
Рейтинг: 0 / 0
08.07.2014, 16:40
    #38690802
yura-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распаковка gzip ответа Http сервера на лету c++ Builder6
В общем в таком виде функция работает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
void StreamUncompress(TMemoryStream *StmDesc, TMemoryStream *StmGzip)
{
  char buf[CHUNK];
  int r=0;

  int fdpipe[2];
  if( _pipe( fdpipe, StmGzip->Size, O_BINARY ) == -1 ) return;

  while( ( r = StmGzip->Read(buf,sizeof(buf))) > 0 ) _write( fdpipe[1], buf, r);
  close(fdpipe[1]);

//  FILE * ffile = fopen("F1.txt", "w");
//  fwrite(buf,sizeof(char),sizeof(buf), ffile);

  AnsiString compressedBytes = AnsiString(buf);
  AnsiString uncompressedBytes = "";

  unsigned full_length = sizeof(buf) ;
  unsigned half_length = full_length / 2;

  unsigned uncompLength = full_length ;
  char* uncomp = (char*) calloc( sizeof(char), uncompLength );

  z_stream strm;
  strm.next_in = (Bytef *) buf;
  strm.avail_in = full_length ;
  strm.total_out = CHUNK;
  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;

  bool done = false ;

  if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK)
  {
    free( uncomp );
    return;
  }

  while (!done) {
    // If our output buffer is too small
    if (strm.total_out >= uncompLength )
    {
      // Increase size of output buffer
      char* uncomp2 = (char*) calloc( sizeof(char), uncompLength + half_length );
      memcpy( uncomp2, uncomp, uncompLength );
      uncompLength += half_length ;
      free( uncomp );
      uncomp = uncomp2 ;
    }

    strm.next_out = (Bytef *) (uncomp + strm.total_out);
    strm.avail_out = uncompLength - strm.total_out;

    // Inflate another chunk.
    int err = inflate (&strm, Z_SYNC_FLUSH);
    if (err == Z_STREAM_END) done = true;
    else if (err != Z_OK)
    {
      break;
    }
  }

  if (inflateEnd (&strm) != Z_OK)
  {
    free( uncomp );
    return;
  }

  for ( size_t i=0; i<strm.total_out; ++i )
  {
    uncompressedBytes += uncomp[ i ];
  }

  char buf2[CHUNK];
  //AnsiString str = "String";
  strcpy(buf2, uncompressedBytes.c_str());

  r = StmDesc->Write(buf2,sizeof(buf2));
  free( uncomp );

//  FILE * file = fopen("F2.txt", "w");
//  fwrite(buf2,sizeof(char),sizeof(buf2), file);

}


требуется довести её до ума, чем и займусь в ближайшее время.
Вызывается она у меня вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
       TStringList *s = new TStringList;
       TMemoryStream *fs = new TMemoryStream();
       TMemoryStream *mstrDesc = new TMemoryStream;   
       IdHTTP1->Post(controllerIP, s, fs);

       if (IdHTTP1->Response->ContentEncoding == "gzip")
       {
          try
          {
             fs->Position = 0;
             StreamUncompress(mstrDesc,fs);
             fs = mstrDesc;
          }
          catch(Exception &e)
          {
             printf(e.Message.c_str());
          }
       }


и запакованный ответ от сервера распаковывается!

Единственное, вызов функции в моей программе происходит в цикле и всегда на 15-й итерации catch выдает access violation. но это уже другая история.
Спасибо всем кто пытался помочь, тема закрыта.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Распаковка gzip ответа Http сервера на лету c++ Builder6 / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]