我最近一直在设置各种测试环境,在此我需要从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都可以解码数据包,但我的软件不能。
答案 0 :(得分:0)
所以问题出在我的gzip函数上,我在这个链接上找到了正确的函数:uncompress error when using zlib
正如Cornstalks上面提到的那样,infalteInit2函数需要将MAX_WBITS + 16作为其最大位大小,我认为这是个问题。如果有人知道任何库或插件来处理这个,请在这里发布!我很惊讶,当HTTP客户端/服务器经常使用时,必须手动编码。