最近給Httpdownload 封裝了支持gzip傳輸
從HTTP的角度
1 客戶端 在http Request Header上帶上 Accept-Encoding:gzip,deflate
2服務器若是支持gzip壓縮則在http reponse eader
部分返回Content-Encoding: gzip 或者Content-Type: application/x-gzip
3將body部分用gzip解壓縮 則得到網頁內容.
傳說中ie有bug 在處理js css壓縮的時候有bug,我不理解 挺簡單的怎么會有bug呢.
從gzip的角度
gzip是一種數據格式 默認且目前僅使用deflate算法壓縮data部分
zlib也是一種數據格式,使用defalte算法壓縮數據部分.
deflate是一種壓縮算法,是huffman編碼的一種加強
zlib是一個開源庫, 提供deflate壓縮和對應的infalte解壓縮.
不過zlib默認的deflate infalte默認是處理zlib格式數據.必須使用
deflateInit2(&strm, DEFAULT_COMPRESSION,Z_DEFLATED, DEFAULT_WINDOWSIZE,DEFAULT_MEMLEVEL, Z_DEFAULT_STRATEGY);
初始化才是處理raw deflate data.(這一點在zlib manul沒有提,在faq中提到,困擾了我好久,還是同事L幫我調試發現)
至于gzip格式解析 對著RFC寫就可以了.
參見RFC 1950 關于zlib http://www.faqs.org/rfcs/rfc1950.html
RFC 1951 關于deflate http://www.faqs.org/rfcs/rfc1951.html
RFC 1952 關于gzip http://www.faqs.org/rfcs/rfc1952.html
nt CGzip::Ungzip(const std::string & inStr , std::string &outStr){
static int nFileCount=0;
nFileCount++;
string strZipFileName="test";
// CConvert::StrToFile(inStr,strZipFileName+CConvert::toString<int>(nFileCount)+"H.gzip"
;
if(inStr.length()<11){
return -1;
}
//process gzip header
unsigned int skipCt = 10;
unsigned int skipZeroCt = 0;
unsigned char ID1 = inStr[0];
unsigned char ID2 = inStr[1];
unsigned char XFL=inStr[8];
bool bFEXTRA = false ;
bool bFNAME = false ;
bool bFCOMMENT = false ;
bool bFHCRC = false ;
unsigned int XLEN = 0;
if( (ID1!=31) && (ID2!=139)){
return -1; //非gzip頭部
}
unsigned char CM = inStr[2];
if(CM!=
{
return -1; //現在都只處理 deflate壓縮的
}
unsigned char FLG = inStr[3];
if( (FLG & GZIP_HEAD_FEXTRA) != 0){
bFEXTRA = true ;
skipCt += 2;
XLEN = inStr[10]+ inStr[11]*256 ;//按照小端字節序列處理
skipCt += XLEN;
}
if( (FLG & GZIP_HEAD_FNAME) != 0){
bFNAME = true;
skipZeroCt++;
}
if( (FLG & GZIP_HEAD_FCOMMENT) != 0){
bFCOMMENT = true;
skipZeroCt++;
}
size_t passedZeroCt = 0;
size_t iStep = skipCt ;
for( size_t iStep = skipCt ; iStep<inStr.length(); iStep++){
if(passedZeroCt>=skipZeroCt){
break;
}
if(inStr[iStep]==''
{
passedZeroCt++;
}
}
skipCt = iStep ;
if( (FLG & GZIP_HEAD_FHCRC) != 0){
bFHCRC = true;
skipCt+=2 ;
}
string coreStr = inStr.substr(skipCt,inStr.length()-8-skipCt);
return CGzip::Inflate(coreStr,outStr);
}
int CGzip:
ogzip(const std::string & inStr , std::string &outStr){
char pAddHead[10];
unsigned long crc = 0;
// gzip header
static const char deflate_magic[2] = {'37', '\213'};
snprintf(pAddHead, 10,
"%c%c%c%c%c%c%c%c%c%c", deflate_magic[0],
deflate_magic[1], Z_DEFLATED, 0 /* flags */,
0, 0, 0, 0 /* 4 chars for mtime */,
0 /* xflags */, 0xff);
string addHead(pAddHead,10);
//gzip's raw deflate body
if(CGzip:
eflate(inStr,outStr)<0){
return - 1;
}
//gzip trailer
crc = crc32(crc, (const Bytef*)inStr.data(), inStr.length());
char tailBuf[8];
memcpy(tailBuf, &crc, 4);
int isize=inStr.size();
memcpy(tailBuf,&isize,4);
string tailStr(tailBuf , 8 );
outStr = addHead + outStr+tailStr; //
return outStr.length(); //