問題:
入問題,問題答案立即呈現在您眼前!
尋找gzip
擷取一個網頁資料傳回的編碼類型是gzip,我該怎麼解壓縮
HTTP頭擷取?
如何用vb擷取網絡上的xml檔案,并解析内容
關于GZIP的解碼
怎樣解gzip的壓縮
請問Wininet是否可以進行Gzip的http傳輸,尤其是post的時候!如果可以如何實作?
關于GZIP格式解壓縮HTTP資料包的問題,我使用ZLIB為什麼必須先儲存檔案,記憶體解壓縮出錯
無法擷取$_SERVER["HTTP_REFERER"]
關于GZIP的問題,高分求解!!
.....
等都是關于gzip解壓的
問題:
提取http的gzip内容,并解壓。
關鍵點:
1 提取http資料包的内容,主要是gzip格式的
2 資料包的重組
3 在記憶體中解壓gzip資料
這兩個周過來,都是在網上過來的,得到網友的幫助不少,很是感激,為了不讓這個問題繼續困擾後來的un_gziper,特寫此文。
1 資料包記憶體的提取:
關鍵的地方是找到gzip記憶體的開始位置以及如何确定gzip内容的大小
開始位置:“Content-Encoding: gzip\r\n\r\n”
gzip大小:“Content-Length:”後面的就是了
2 資料包的重組,一般網頁的内容很少是一個資料包可以裝得下的,是以都得進行gzip之後再用多個資料包進行傳輸
關鍵的地方是:
get請求資料包的ack和seq與http傳回資料包的ack,seq有密切的聯系:
舉例說明:
get請求:ack=0,seq=0
http1:seq=0,ack=584
http2: seq=1420,ack=584
...
簡單的分析說明可以看出,我們的算法設計:
首先得到get請求的ack,傳回的資料包的seq等于這個值,同時記下這個資料包的ack,後面進行分包發送的http的資料包的ack都是這個值,這個是關鍵點之一,同時綜合
Content-Length就可以得到gzip的全部内容。
至此,原始資料提取完畢,該是如何解壓的問題了
3解壓gzip
我做了上面的1,2步以後将内容儲存到檔案裡面,用gzip指令可以打開,驗證了資料的完整性。
而後我采用了zlib提供的uncompress函數,和大多數的網友一樣,都是犯了一個緻命的錯誤,沒有仔細的閱讀zlib的文檔!導緻一次次無謂的識别!
事實上zlib格式和gzib格式是有差别的,而uncompress是用來解壓zlib格式檔案的,這就是為什麼會出現用compress函數壓縮的資料,在記憶體中可以直接用uncompress函數進行解壓的,而就不能解壓gzip資料的問題!
後來測試了zlib包裡面的example例子,算是對zlib有了一點點的了解,應該用inflate類函數進行解壓!
當然這樣遇到了問題,格式不對!
後來在網上看到的文章:gzip格式用inflate函數還不行,必需要用inflateInit2(&strm, 47); !!!!!!!!!!!!!!!!!!
問題解決!
這裡借用那位網友的源代碼,同時對他表示感謝!
int inflate_read(char *source,int len,char **dest,int gzip)
{
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int totalsize = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if(gzip)
ret = inflateInit2(&strm, 47);
else
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
strm.avail_in = len;
strm.next_in = source;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
totalsize += have;
*dest = realloc(*dest,totalsize);
memcpy(*dest + totalsize - have,out,have);
} while (strm.avail_out == 0);
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
後記,這個過程是痛苦的,但也是幸福的!
這裡我發起一個小小的倡議,對所有關注gzip解壓的問題的網友:
我們都遇到了一個問題就是zlib的文檔都是英文的,有個别網友翻譯了開頭的一小部分,但是這是不夠的!
是以,我希望有興趣的朋友可以一起來幫zlib的文檔翻譯成為中文!
有興趣的可以加我!
閱讀(2738) | 評論(0) | 轉發(0) |