C - 解压缩 Gzipped http 响应

标签 c http sockets gzip gnu

我在解压缩 gzip 压缩的 http 响应时遇到了一些问题,我将数据部分与 header 分开,但它的 gzip header 和消息包含\0 个字符,char * 将其作为空终止符,所以第一个问题是如何提取 gzip 压缩 block ?

我不能使用像 strcat、strlen 这样的字符串函数,因为它是压缩的 gzip 数据,在 block 内的不同位置包含\0 字符。

我使用过 libcurl,但它比 C 套接字相对慢。

以下是示例响应的一部分:

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
P3P: CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND"
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 12605
Date: Mon, 05 Mar 2012 11:46:30 GMT
Connection: keep-alive
Set-Cookie: _FP=EM=1; expires=Wed, 05-Mar-2014 11:46:29 GMT; domain=.bing.com; path=/

����ՠ����AU��o�

示例代码:

#define MAXDATASIZE 1024

char *recvData; // Holds entire gzip data
char recvBuff[MAXDATASIZE]; // Holds gzip chunk
int offset=0;
while(1){
    recvBytes = recv(sockfd, &recvBuff, MAXDATASIZE-1, 0);
    totalRecvBytes += recvBytes;

    // get content length, this runs first time only as required
    if(!clfnd){
        regi = regexec(&clregex, &recvBuff, 3, clmatch, 0);
        if(!regi){
            strncpy(clarr, recvBuff + clmatch[2].rm_so, clmatch[2].rm_eo-clmatch[2].rm_so);
            clarr[clmatch[2].rm_eo-clmatch[2].rm_so] = '\0';
            cl = atoi(clarr);
            clfnd=1;
            regfree(&clregex);
            recvData = malloc(cl * sizeof(char));
            memset(recvData, 0, sizeof recvData);
        }
    }

    // get data part from 1st iteration, furthur iterations contain only data
    if(!datasplit){
        int strtidx;
        char *datastrt = strstr(&recvBuff, "\r\n\r\n");
        if(datastrt != NULL){
            strtidx = datastrt - recvBuff + 4;
            memcpy(recvData, recvBuff + strtidx, recvBytes-strtidx);
            datasplit=1;
            offset = recvBytes-strtidx;
        }
    }
    else{
        memcpy(recvData + offset, recvBuff, recvBytes);
        offset += recvBytes;
    }
    if (offset >= cl)
        break;
}

char *outData = malloc(offset*4 * sizeof(char));
memset(outData, 0, sizeof outData);
int ret = inf(recvData, offset, outData, offset*4);

膨胀函数:

int inf(const char *src, int srcLen, const char *dst, int dstLen){
z_stream strm;
strm.zalloc=NULL;
strm.zfree=NULL;
strm.opaque=NULL;

strm.avail_in = srcLen;
strm.avail_out = dstLen;
strm.next_in = (Bytef *)src;
strm.next_out = (Bytef *)dst;

int err=-1, ret=-1;
err = inflateInit2(&strm, MAX_WBITS+16);
if (err == Z_OK){
    err = inflate(&strm, Z_FINISH);
    if (err == Z_STREAM_END){
        ret = strm.total_out;
    }
    else{
        inflateEnd(&strm);
        return err;
    }
}
else{
    inflateEnd(&strm);
    return err;
}
inflateEnd(&strm);
printf("%s\n", dst);
return err;
}

最佳答案

不,char * 类型没有说明它指向的内容,也没有将任何值解释为终止符。另一方面,str* 函数对字符串的表示方式有一个假设,不能用于二进制数据,甚至不能用于具有不同表示的文本数据。

解压可能相当复杂,但你可以看看zlib ,应该能够帮助您。

关于C - 解压缩 Gzipped http 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9566340/

相关文章:

c - 单行注释宏扼杀了 gcc

http - 远程连接EC2服务器上的MongoDB http接口(interface)

security - 从 EJB 调用 HTTP 时如何传播 WebSphere 安全 token

macos - Swift 中的授权

python - 保持 TCP 套接字连接事件和读/写协调

C 编程 : Recursion

c - 字符串转换时 strtol 结果不匹配

c - 纯C代码示例中的utf8到char编码

c# - 在 ASP.NET 中获取 HTTP Referrer

用于处理完整接收的 C 套接字