解压缩HTTP gzipped响应时遗漏了某些内容

时间:2018-03-16 15:27:46

标签: c++ qt http gzip

我最近一直在设置各种测试环境,在此我需要从HTTP服务器读取和解码gzip响应。我知道我到目前为止所做的工作,因为我已经使用wireshark和硬编码数据测试了它,如下所述,我的问题是我如何处理来自HTTP服务器的gizzped数据有什么问题?

以下是我使用的内容:

从这个帖子http://www.qtcentre.org/threads/30031-qUncompress-data-from-gzip我使用gzipDecopress函数和提供的数据,看看它是否有效。

QByteArray gzipDecompress( QByteArray compressData )
{

//Hardcode sample data
const char dat[40] = {
            0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAA, 0x2E, 0x2E, 0x49, 0x2C, 0x29,
            0x2D, 0xB6, 0x4A, 0x4B, 0xCC, 0x29, 0x4E, 0xAD, 0x05, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00,
            0x2A, 0x63, 0x18, 0xC5, 0x0E, 0x00, 0x00, 0x00};
compressData = QByteArray::fromRawData( dat, 40);

//decompress GZIP data

   //strip header and trailer
     compressData.remove(0, 10);
     compressData.chop(12);

     const int buffersize = 16384;
     quint8 buffer[buffersize];

     z_stream cmpr_stream;
     cmpr_stream.next_in = (unsigned char *)compressData.data();
     cmpr_stream.avail_in = compressData.size();
     cmpr_stream.total_in = 0;

     cmpr_stream.next_out = buffer;
     cmpr_stream.avail_out = buffersize;
     cmpr_stream.total_out = 0;

     cmpr_stream.zalloc = Z_NULL;
     cmpr_stream.zalloc = Z_NULL;

     if( inflateInit2(&cmpr_stream, -8 ) != Z_OK) {
             qDebug() << "cmpr_stream error!";
     }

       QByteArray uncompressed;
       do {
               int status = inflate( &cmpr_stream, Z_SYNC_FLUSH );

               if(status == Z_OK || status == Z_STREAM_END) {
                       uncompressed.append(QByteArray::fromRawData((char *)buffer, buffersize - cmpr_stream.avail_out));
                       cmpr_stream.next_out = buffer;
                       cmpr_stream.avail_out = buffersize;
               } else {
                        inflateEnd(&cmpr_stream);
                       }

               if(status == Z_STREAM_END) {
                   inflateEnd(&cmpr_stream);
                   break;
               }

       }while(cmpr_stream.avail_out == 0);

       return uncompressed;

}

当数据在该示例中被硬编码时,字符串被解压缩。但是,当我从HTTP服务器读取响应并将其存储在QByteArray中时,它无法解压缩。我正在阅读如下的响应,我可以看到它在wireshark

上比较结果时有效
        //Read that length of encoded data
        char EncodedData[ LengthToRead ];
        memset( EncodedData, 0, LengthToRead );
        recv( socketDesc, EncodedData, LengthToRead, 0 );
        EndOfData = true;

        //EncodedDataBytes = QByteArray((char*)EncodedData);
        EncodedDataBytes = QByteArray::fromRawData(EncodedData, LengthToRead );

我认为在阅读响应时我缺少一些标题或字节顺序,但此刻不知道是什么。任何帮助都非常欢迎!!

编辑:所以我在周末一直在看这个,现在我试图测试给定十六进制字符串的编码和解码,这是纯文本中的“{status:false}”。我曾尝试使用在线gzip编码器,如http://www.txtwizard.net/compression,但它返回一些与上述代码中的十六进制字符串不匹配的ascii文本。当我使用PHP gzcompress(“{status:false}”,1)函数时,它给了我非ascii值,我无法复制/粘贴到测试,因为它们是ascii。所以我想知道gzip编码/解码是否有任何标准参考?它绝对不是一些特殊的编码,因为firefox和wireshark都可以解码数据包,但我的软件不能。

1 个答案:

答案 0 :(得分:0)

所以问题出在我的gzip函数上,我在这个链接上找到了正确的函数:uncompress error when using zlib

正如Cornstalks上面提到的那样,infalteInit2函数需要将MAX_WBITS + 16作为其最大位大小,我认为这是个问题。如果有人知道任何库或插件来处理这个,请在​​这里发布!我很惊讶,当HTTP客户端/服务器经常使用时,必须手动编码。