![]() |
gzip decompression, browser (delphi)
вопрос:
есть html страница... скажем zalil.ru (для примера) ответ от сервера при её запросе выглядит так: Код:
HTTP/1.1 200 OKКод:
HTTP/1.1 200 OK1. Откуда считать начало gzip тела (которое длинной 6da) - с начала строки, следующей за строкой с размером и до строки с нулем без учета символов переноса строки перед нулем? 2. как конвертнуть текст gzip обратно в нормальный? ф-цией (из либы ZLibEx) Код:
function DecompressString(const aString: string): string;reply:=copy(reply,pos('6da',reply)+3,1754); //1745 это 6da где reply - изначально полученный мной от сервера ответ. Прошу показать как с этим справиться конкретно на примере страницы zalil.ru, т.к. она маленькая + неизменяющаяся. Но можно и на любой другой ps. вожусь с этой *ней уже часов 6. за реальную помощь в решении вопроса преобразования gzip в обычный текст при использовании сокетов (никаких компонет, никакого инди - мне 1000-1500 потоков надо - инди убьет себя) с меня +20 |
Пробуй передавать на вход своей функции не переменную типа String, а какую-нибудь переменную типа TMemoryStream, так как String не сможет сохранить в себе все символы, которые передает тебе сервер.
|
так... окей.
Начало блока gzip - пара байт: 0x1f,0x8b (так подсказал RFC 1952) длинна блока... наверное 6da (или любая другая хекс-цифра, которая идет перед шифроблоком и вероятно обозначает его длинну) тем не менее, как я не варьирую длинну блока (исходя из того, что первый символ блока - 0x1f) - все равно получаю "data error" :-( Chrome~ - хз.. ф-ция, что я указал (найденная в гугле) вроде как работает именно с переменной string. хотя фиг его знает что тут как, если быть до конца точным |
http://en.wikipedia.org/wiki/Chunked_transfer_encoding
то есть Код:
aКод:
<тут A символов><тут 6da символов> |
Цитата:
Дело в том, что основные "тесты" я провожу, конечно же, не на паге zalil.ru. Та пага, где я тестюсь идет не chunked а единым блоком...( и увы преобразовать её (как и любую другую, не-chunked) из gzip в обычный текст обозначенный выше ф-цией не получается (почему именно - фиг его знает. "data error") было бы супер, если бы гашелся кто-то, ко когда-нибудь реализовывал комбинацию delphi+windows_sockets+gzip |
Мож баг в распаковщике? Ты попробуй полученный код распаковать в php
и если удастся, нормально, значит баг в модуле |
Распаковка gzip (взято отсюда - http://www.rsdn.ru/forum/winapi/2171857.flat.aspx):
Код:
может учитывал лишние \r\n символы? |
Цитата:
Знаешь ли, не всегда просто перевести код (который не понимаешь) с одного языка, который плохо понимаешь на другой, который, пусть даже, и знаешь более менее неплохо. |
delphi zlib 1.2.3.2009
# zlib version 1.2.3 for delphi 5, 6, 7, 8, 2005, 2006, 2007, 2009 # now supports simple gzip files # includes zlib source code and c++ builder 6 project files (c++ builder 6 was used to compile c source into object files) http://www.base2ti.com/zlib.htm |
можно гору обойти:
в заголовок-запроса напиши так чтоб сервер не паковал данные |
Цитата:
|
Цитата:
может конечно мало *лся... там есть какие-то ф-ции для работы с "потоковыми данными" итд. Хотя.. все же хотелось бы по возможности увидеть готовый пример. maestro-ant - хром уже ответил. "Не паковать данные"? - я и так их(в данный момент) не пакую... потому что не умею распаковывать:( Но хотелось бы все-таки научиться, чтобы уменьшить затраты траффика => увеличить количество обрабатываемых http страниц в минуту. |
ErrorNeo, юзай либкурл и будет тебе счастье ;)
|
Chrome~
попрошу без оскорблений. ErrorNeo Мой совет вполне дельный. Разве тебе критично-нужно чтоб трафик был упакованный? Если нет, то в заголовке запроса, который отсылаешь серверу нужно выкинуть строчку Accept-encoding gzip. И все! упаковка данных происходить не будет. Я так делал когда писал "подмену выдачи". gzip-тупо не нужен мне был. Она нужна для экономии трафика. |
Цитата:
|
Цитата:
Тоже интересуюсь данным вопросом, раньше искал ответ, но так и не нашел. |
да, знаю, что либкурл поможет(((
но в данном случае доделаю всё и без коспрессии, а дальше... если еще 1 приложение придется писать такое - а полюбому придется - буду уже юзать.... либкурл :'( (прогонять полтора террабафта траффика вообще без компрессии это все излишне же сурово, даже для меня) maestro-ant - да, мне критична именно экономия траффика. Без упаковки я запросы и так умею слать - да и любой дурак умеет. Не в обиду тебе.) А вот распавовывать пакованные методами дельфи - увы - далеко не каждый. Если быть точнее - то судя по этой теме вообще никто это не делал у нас при использовании вин-сок, да и... вообще хоть каким-либо методом на дельфи. обломно. |
Пробовал TIdCompressorZLib прикрутить? Что-то мне кажется что не пробовал
Кстати реальный пример того что библиотеки типа инди не хуже винсок. Гзип уменьшает трафф на порядка 70%, вот и посчитайте сколько страниц можно получить в инди и в винсок за промежуток времени |
ErrorNeo если еспользуется Indy 9(Delphi 7), то багов в ней куча и gzip там попросту не работает. Для этого нужно скачать заплатки этой версии(там вполть до Classes) :)
Вот архив : http://slil.ru/28913262 Распаковывешь эту папку в папку сос воей прогой и все *.pas подключаем к проекту через Project Manager, перезапускаем Delphi и используем как пытались, могу поспорить в этом беда. |
Блин, я туплю, но один фик посмотреть те сорцы можно и вытащить для себя то что нужно:)
|
Цитата:
|
А нахрена 1000 потоков если и 300 упирается в лимит траффа?
Инди дохрена процессорного времени отбирает? |
Цитата:
Цитата:
|
Цитата:
И кстати если при большом количестве у вас начинает в инди сыпаться мног ошибок - скорее всего плохая синхронизация потоков. Есть в инди одно узкое конечно место где все потоки сходятся, но там всё идеально сделано.(Файл IdComponent.pas, создание класса) Там речь идёт о критической секции и прикол в том что на XP(ещё где хз) при огромном количестве потоков эти критические секции(по сути системные объекты) глючат(пропускают потоки, когда главный поток блокирует), не объяснимо но факт. Может там трабла, я хз. |
Цитата:
|
Цитата:
Цитата:
|
как плавно съехали с gzip.. :)
по сабжу: что-то GZDecompressStr не хочет работать с результатом GZCompressStr.. Data Error! В чем прикол? |
Вот нашел в нете функцию позволяющую распаковывать gzip без заголовка(10 байт) и окончания (8 байт=CRC32+длинна исходного текста). На залил ру ответ без окончания.
а вообще ошибка возникала из-за того что в TZDecompressionStream используется InflateInit_ в котором по-умолчанию стоит windowBits=15, а нужно windowBits=-15 , что и указывается в InflateInit2_ (хотя сам адлер пишет что этот параметр должен быть в диапазоне 8..15). Вот код: Код:
function InflateInit2(var stream: TZStreamRec; windowBits: Integer): Integer; |
| Время: 23:02 |