mfc的http报文压缩

现象:使用mfc的http请求类CHttpConnection时,由于服务返回的报文有做压缩,但是mfc的这个类貌似没有自动实现解压缩,导致收到的报文是乱码或报文不全。

解决办法:根据返回的请求头信息,查看里面是否有CONTENT_ENCODING属性,如果有,则自己解压一下,这个属性网上资料很多,解压的方法也比较多。

代码段示列如下:

CString contentEncode;
        m_pFile->QueryInfo(HTTP_QUERY_CONTENT_ENCODING, contentEncode);
        if (0 == contentEncode.Compare(_T("gzip"))){
            ungzip(strRawResponse, responseLength, recvEncode);
        }else
            memcpy(recvEncode, strRawResponse, responseLength);

//解压代码:该段参考网上的代码。

int ungzip(char* source, int len, char*des)
{
    int ret, have;
    int offset = 0;
    z_stream d_stream;
    Byte compr[LENGTH] = { 0 }, uncompr[LENGTH * 4] = { 0 };
    memcpy(compr, (Byte*)source, len);
    uLong comprLen, uncomprLen;
    comprLen = len;//一开始写成了comprlen=sizeof(compr)以及comprlen=strlen(compr),后来发现都不对。

    //sizeof(compr)永远都是segment_size,显然不对,strlen(compr)也是不对的,因为strlen只算到\0之前,

    //但是gzip或者zlib数据里\0很多。
    uncomprLen = LENGTH * 4;
    strcpy((char*)uncompr, "garbage");

    d_stream.zalloc = Z_NULL;
    d_stream.zfree = Z_NULL;
    d_stream.opaque = Z_NULL;

    d_stream.next_in = Z_NULL;//inflateInit和inflateInit2都必须初始化next_in和avail_in
    d_stream.avail_in = 0;//deflateInit和deflateInit2则不用

    ret = inflateInit2(&d_stream, 47);
    if (ret != Z_OK)
    {
        printf("inflateInit2error:%d", ret);
        return ret;
    }
    d_stream.next_in = compr;
    d_stream.avail_in = comprLen;
    do
    {
        d_stream.next_out = uncompr;
        d_stream.avail_out = uncomprLen;
        ret = inflate(&d_stream, Z_NO_FLUSH);
        //assert(ret != Z_STREAM_ERROR);
        switch (ret)
        {
        case Z_NEED_DICT:
            ret = Z_DATA_ERROR;
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            (void)inflateEnd(&d_stream);
            return ret;
        }
        have = uncomprLen - d_stream.avail_out;
        memcpy(des + offset, uncompr, have);//这里一开始我写成了memcpy(des+offset,d_stream.next_out,have);

        //后来发现这是不对的,因为next_out指向的下次的输出,现在指向的是无有意义数据的内存。见下图

        offset += have;

    } while (d_stream.avail_out == 0);
    inflateEnd(&d_stream);
    memcpy(des + offset, "\0", 1);
    return ret;
}

 

注意:需要自己下一下zlib的动态链接库,自己windows带的可能用不了。 zlib1.dll

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六个沃德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值