1. 程式人生 > >獲取http的gzip內容並解壓

獲取http的gzip內容並解壓

08年在csdn上面寫了一個帖子關於解壓http的gzip內容的,一直以來有不少的程式設計師前仆後繼,持續的遇到同樣的問題,正如我08年遇到的時候看的都是03 04年的帖子一樣,現在把論壇上面的資料整理一下放到這裡,希望能這個問題不會再困擾其他的程式設計師。

------------------------------

尋找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); !!!!!!!!!!!!!!!!!!
問題解決!
這裡借用那位網友的原始碼,同時對他表示感謝!

補充:zlib版本需要在1.1.4以上(不包括)