woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

支持gzip的爬虫 gzip zlib deflate 相关介绍

最近给Httpdownload 封装了支持gzip传输

 

HTTP的角度

1 客户端 http Request  Header上带上 Accept-Encoding:gzip,deflate

2服务器若是支持gzip压缩则在http reponse eader

部分返回Content-Encoding: gzip 或者Content-Type: application/x-gzip

3body部分用gzip解压缩 则得到网页内容.

传说中iebug 在处理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"clip_image001;
    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!=clip_image002{
        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]==''clip_image001{
                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:clip_image003ogzip(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:clip_image003eflate(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(); //

posted on 2009-09-07 21:58 肥仔 阅读(2505) 评论(0)  编辑 收藏 引用 所属分类: 库 & 代码段HTTP & URL


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理