GZIP相关操作

GZIP压缩

zlib是一个通用的压缩开源库,提供了在内存中压缩和解压的函数,包括对解压后数据的校验。目前版本的zlib只支持deflate方法,但是其它的方法将会被添加进来并且拥有同样的接口。

—— zlib manaul
    deflate算法在rfc1951中有详细的说明。

    zlib同时又是一种数据格式,使用zlib库压缩后的数据会在deflate数据的头和尾添加信息,形成zlib格式的数据。

   gzip也是一种数据压缩格式,可以大体分为头部,数据部和尾部三个部分,其中头部和尾部主要是一些文档属性和校验信息(rfc1952),数据部主要是用deflate方法压缩得到的数据。
   
    zlib库默认的压缩方法并不是gzip的,而是zlib的,因此使用zlib压缩得到gzip格式的数据有两种方法:

  1. 使用zlib提供的gz***系列函数可以直接把想要的内容写入一个磁盘gzip文件;
  2. 如果想在内存中生成gzip格式的数据,可以在初始化的时候调用inflateInit2函数,并指定为gzip格式,代码如下:

 

  z_stream d_stream;
  d_stream. zalloc = NULL;
  d_stream. zfree = NULL;
  d_stream. opaque = NULL;
  int ret = deflateInit2( & d_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, DEFAULT_WINDOWSIZE, DEFAULT_MEMLEVEL,   Z_DEFAULT_STRATEGY) ;

  if ( Z_OK ! = ret )
  {
    printf( "init deflate error/n" ) ;
    return ret ;
  }

    之后,用deflate压缩出来的数据就是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"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_image003 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:clip_image003 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(); //

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <zlib.h>
/* Compress data */
int zcompress(Bytef *data, uLong ndata,
Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;

if(data && ndata > 0)
{
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
if(deflateInit(&c_stream, Z_DEFAULT_COMPRESSION) != Z_OK) return -1;
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while (c_stream.avail_in != 0 && c_stream.total_out < *nzdata)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for (;;) {
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(deflateEnd(&c_stream) != Z_OK) return -1;
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}

/* Compress gzip data */
int gzcompress(Bytef *data, uLong ndata,
Bytef *zdata, uLong *nzdata)
{
z_stream c_stream;
int err = 0;

if(data && ndata > 0)
{
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
-MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK) return -1;
c_stream.next_in = data;
c_stream.avail_in = ndata;
c_stream.next_out = zdata;
c_stream.avail_out = *nzdata;
while (c_stream.avail_in != 0 && c_stream.total_out < *nzdata)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) return -1;
}
if(c_stream.avail_in != 0) return c_stream.avail_in;
for (;;) {
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(deflateEnd(&c_stream) != Z_OK) return -1;
*nzdata = c_stream.total_out;
return 0;
}
return -1;
}

/* Uncompress data */
int zdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream; /* decompression stream */

d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit(&d_stream) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK) return -1;
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}

/* HTTP gzip decompress */
int httpgzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}

/* Uncompress gzip data */
int gzdecompress(Byte *zdata, uLong nzdata,
Byte *data, uLong *ndata)
{
int err = 0;
z_stream d_stream = {0}; /* decompression stream */
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = zdata;
d_stream.avail_in = 0;
d_stream.next_out = data;
if(inflateInit2(&d_stream, -MAX_WBITS) != Z_OK) return -1;
//if(inflateInit2(&d_stream, 47) != Z_OK) return -1;
while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;
if(err != Z_OK )
{
if(err == Z_DATA_ERROR)
{
d_stream.next_in = (Bytef*) dummy_head;
d_stream.avail_in = sizeof(dummy_head);
if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)
{
return -1;
}
}
else return -1;
}
}
if(inflateEnd(&d_stream) != Z_OK) return -1;
*ndata = d_stream.total_out;
return 0;
}

#ifdef _DEBUG_ZSTREAM
#define BUF_SIZE 65535
int main()
{
char *data = "kjdalkfjdflkjdlkfjdklfjdlkfjlkdjflkdjflddajfkdjfkdfaskf;ldsfk;ldakf;ldskfl;dskf;ld";
uLong ndata = strlen(data);
Bytef zdata[BUF_SIZE];
uLong nzdata = BUF_SIZE;
Bytef odata[BUF_SIZE];
uLong nodata = BUF_SIZE;

memset(zdata, 0, BUF_SIZE);
//if(zcompress((Bytef *)data, ndata, zdata, &nzdata) == 0)
if(gzcompress((Bytef *)data, ndata, zdata, &nzdata) == 0)
{
fprintf(stdout, "nzdata:%d %s/n", nzdata, zdata);
memset(odata, 0, BUF_SIZE);
//if(zdecompress(zdata, ndata, odata, &nodata) == 0)
if(gzdecompress(zdata, ndata, odata, &nodata) == 0)
{
fprintf(stdout, "%d %s/n", nodata, odata);
}
}
}

/*

获取gzip文件解压后文件大小


*/
#include 
< stdio.h >
int  main()
{
    FILE 
*  pFile  =  NULL;
    
int  nRes  =   0 ;
    
int  nUnCompressSize  =   0 ;
    pFile 
=  fopen( " test.gz " , " r " );
    
if  ( ! pFile )
        
goto  Exit0;
    nRes 
=  fseek(pFile,  - 4 , SEEK_END);
    
if  (nRes)
        
goto  Exit0;
    fread(
& nUnCompressSize, sizeof ( int ), 4 ,pFile);
    printf(
" uncompress file size %d /n " ,nUnCompressSize);
Exit0:
    
if (pFile)
    {
       fclose(pFile);
    }
    
return   0 ;
}

#endif
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Nginx中启用gzip压缩,您需要在nginx.conf配置文件中添加以下行: ``` gzip on; gzip_types image/png image/jpeg image/gif; ``` 这将启用gzip压缩,并指定要压缩的文件类型。在这个例子中,我们指定了png、jpeg和gif格式的文件。 如果您想要更细粒度的控制,您可以使用gzip_comp_level指令来指定压缩级别。例如: ``` gzip on; gzip_types image/png image/jpeg image/gif; gzip_comp_level 6; ``` 这将启用gzip压缩,并指定要压缩的文件类型和压缩级别。在这个例子中,我们指定了png、jpeg和gif格式的文件,并使用级别6进行压缩(默认级别是1)。 如果您想要压缩所有的静态文件,而不是只压缩指定类型的文件,您可以使用以下配置: ``` gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml+rss; gzip_min_length 1000; gzip_http_version 1.1; gzip_comp_level 6; gzip_vary on; gzip_proxied any; gzip_buffers 16 8k; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; ``` 这将启用gzip压缩,并压缩所有指定类型的文件。gzip_min_length指令指定要压缩的文件的最小长度(默认是20字节)。gzip_http_version指令指定要使用的HTTP版本(默认是1.0)。gzip_comp_level指令指定压缩级别。gzip_vary指令指定是否发送Vary头(默认是关闭的)。gzip_proxied指令指定启用哪些代理服务器。gzip_buffers指令指定压缩缓存大小。gzip_disable指令指定禁用压缩的浏览器类型。 有关更多信息,请参阅Nginx文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值