From 4189d07c837e66f4cda92820477f5fb0e3d9315c Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Thu, 31 May 2012 14:42:32 +0200 Subject: QtNetwork: handle raw deflate compressed data in Http. For raw deflate compressed data with no zlib or gzip header we need to call initInflate2 with -MAX_WBITS. The first call to inflate will asume that the data has a header, but if that call fails with a Z_DATA_ERROR we can try once more with changed windowBits incase the data was raw compressed data without a header. Task-number: QTBUG-25513 Change-Id: Ib37c286c6da6d5395581717d0e76a0dbd5df289c Reviewed-by: Shane Kearns --- src/network/access/qhttpnetworkreply.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/network/access/qhttpnetworkreply.cpp') diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index b95a227467..8c8c834042 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -685,6 +685,7 @@ qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QByteDataBuff #ifndef QT_NO_COMPRESS qint64 QHttpNetworkReplyPrivate::uncompressBodyData(QByteDataBuffer *in, QByteDataBuffer *out) { + bool triedRawDeflate = false; for (int i = 0; i < in->bufferCount(); i++) { QByteArray &bIn = (*in)[i]; @@ -700,8 +701,26 @@ qint64 QHttpNetworkReplyPrivate::uncompressBodyData(QByteDataBuffer *in, QByteDa int ret = inflate(&inflateStrm, Z_NO_FLUSH); //All negative return codes are errors, in the context of HTTP compression, Z_NEED_DICT is also an error. - if (ret < 0 || ret == Z_NEED_DICT) + // in the case where we get Z_DATA_ERROR this could be because we recieved raw deflate compressed data. + if (ret == Z_DATA_ERROR && !triedRawDeflate) { + inflateEnd(&inflateStrm); + triedRawDeflate = true; + inflateStrm.zalloc = Z_NULL; + inflateStrm.zfree = Z_NULL; + inflateStrm.opaque = Z_NULL; + inflateStrm.avail_in = 0; + inflateStrm.next_in = Z_NULL; + int ret = inflateInit2(&inflateStrm, -MAX_WBITS); + if (ret != Z_OK) { + return -1; + } else { + inflateStrm.avail_in = bIn.size(); + inflateStrm.next_in = reinterpret_cast(bIn.data()); + continue; + } + } else if (ret < 0 || ret == Z_NEED_DICT) { return -1; + } bOut.resize(bOut.capacity() - inflateStrm.avail_out); out->append(bOut); if (ret == Z_STREAM_END) -- cgit v1.2.3