最近给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(); //