1. 程式人生 > >關於獲取http的gzip內容並解壓

關於獲取http的gzip內容並解壓

網上很多程式碼,都是以下的程式碼。我自己用SOCKET實現的時候(呼叫ZLIB庫),發現都是可以的。

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;   
}

而昨天用在WININET的返回資料裡面的時候,發現不行。於是去搜索資料,參考了一些資料之後,發現WININET添加了gzip的頭部,於是自己參考了

https://github.com/wkoszek/mini_gzip

寫了一個函式。並且,miniz.c的程式碼裡面和zlib的略不同,需要把上面一個函式的47修改成 -MZ_DEFAULT_WINDOW_BITS。

int mini_gz_get_data_offset(const unsigned char *buffer, int bufferlength)
{
	int offset;
	int result = 0;

	if (10 < bufferlength)
	{
		buffer + 0;		// .gz header

		if (buffer[0] == 0x1F && buffer[1] == 0x8B && buffer[2] == 0x08)
		{
			// auxillary header
			offset = 10;

			if (buffer[3] & 0x4)
			{
				//fextra_len = buffer[offset + 1] << 8 | buffer[offset + 0];
				offset += 2;
				//fextra_ptr = &buffer[offset];
			}
			if (buffer[3] & 0x8)
			{
				//fname_ptr = &buffer[offset];
				while (buffer[offset++] != '\0')
				{
					;
				}
			}
			if (buffer[3] & 0x10)
			{
				//fcomment_ptr = &buffer[offset];
				while (buffer[offset++] != '\0')
				{
					;
				}
			}
			if (buffer[3] & 0x2)
			{
				//fcrc = *(unsigned short *)&buffer[offset];
				offset += 2;
			}

			result = offset;
		}
	}
	return (result);
}

希望後來的人可以少走彎路。