寻找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); !!!!!!!!!!!!!!!!!!
问题解决!
这里借用那位网友的源代码,同时对他表示感谢!
int inflate_read(char *source,int len,char **dest,int gzip)
{
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int totalsize = 0;
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if(gzip)
ret = inflateInit2(&strm, 47);
else
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
strm.avail_in = len;
strm.next_in = source;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
totalsize += have;
*dest = realloc(*dest,totalsize);
memcpy(*dest + totalsize - have,out,have);
} while (strm.avail_out == 0);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
Int32 uncompressGzip(UInt8* pSrc, UInt32 srcSize,char**pOutDest, UInt32* pOutBufSize)
{
Int32 ret = OK;
UInt8* pBuf = pSrc+ (srcSize - 1);
uLongf len =*pBuf;
Int32uncompressResult;
z_stream d_stream;
//check gz file,rfc1952 P6
if((*pSrc !=0x1f)||(*(pSrc+1) != 0x8b))
{
DBG_ERR(("uncompressGzip non Gzip"));
return ERR;
}
for(inti = 0; i < 3; i++)
{
pBuf--;
len <<= 8;
len += *pBuf;
}
//fortest
if((len== 0) || (len > 1000000))
{
DBG_ERR(("uncompressGzip,error gzip!"));
return ERR;
}
char*pDesBuf = (char*)memAlloc(len);
//gzipdecompression start!!!
d_stream.zalloc =Z_NULL;
d_stream.zfree =Z_NULL;
d_stream.opaque = Z_NULL;
d_stream.next_in =Z_NULL;
d_stream.avail_in= 0;
uncompressResult =inflateInit2(&d_stream,47);
if(uncompressResult!=Z_OK)
{
printf("inflateInit2 error:%d",uncompressResult);
returnuncompressResult;
}
d_stream.next_in=pSrc;
d_stream.avail_in=srcSize;
d_stream.next_out=(Bytef *)pDesBuf;
d_stream.avail_out=len;
uncompressResult =inflate(&d_stream,Z_NO_FLUSH);
switch(uncompressResult)
{
caseZ_NEED_DICT:
uncompressResult = Z_DATA_ERROR;
caseZ_DATA_ERROR:
caseZ_MEM_ERROR:
(void)inflateEnd(&d_stream);
returnuncompressResult;
}
printf("outlen= %d, total_in= %d, total_out= %d, avail_out= %d@@@@@@@@@@@\n",len, d_stream.total_in, d_stream.total_out, d_stream.avail_out);
inflateEnd(&d_stream);
*pOutBufSize = len-2;
*pOutDest = pDesBuf;
returnret;
}
转自:http://hi.baidu.com/oathevil/blog/item/702f54cd2ce0531b00e9285d.html
目前工作:接受串口发来的数据,数据经过gzip压缩,编码格式为utf8,json,刚接触此类工作五天,很烦,问题还是没有解决,上面是网友的代码,编译没问题,但是得不到想要的结果,继续加油~