PDA

View Full Version : qUncompress with QHttp gzipped response



ricky92
27th November 2009, 15:58
Hello, I'm new to the forums and I joined because I'm having a problem with a Qt4 function, qUncompress. In the documentation it says that if the string has been compressed with zlib or an external application, you should prepend 4 bytes containing the expected lenght of the uncompressed string... How would I do that? I tried converting the .size() unsigned int value to a byte array (using some method I found on the internet) but it failed. Could anyone please help me?
Thanks in advance. :)

squidge
27th November 2009, 18:13
Some rough code would be:

QByteArray ba;

ba.append(size >> 24);
ba.append(size >> 16);
ba.append(size >> 8);
ba.append(size);

uncompressed.prepend(ba);

ricky92
27th November 2009, 19:26
Some rough code would be:

QByteArray ba;

ba.append(size >> 24);
ba.append(size >> 16);
ba.append(size >> 8);
ba.append(size);

uncompressed.prepend(ba);
Tried that, it gives me the following error in the Application Output:

qUncompress: Z_DATA_ERROR: Input data is corrupted

This is my code:


QByteArray responseBytes = currentClient->readAll();
QString responseHTML;

if (responseHeaders.hasKey("Content-Encoding") && responseHeaders.value("Content-Encoding") == "gzip")
{
QByteArray inflatedResponse;

unsigned int byteSize = responseBytes.size();
QByteArray bytes;

bytes.append(byteSize >> 24);
bytes.append(byteSize >> 16);
bytes.append(byteSize >> 8);
bytes.append(byteSize);

responseBytes.prepend(bytes);

inflatedResponse = qUncompress(responseBytes);

responseHTML = QString(inflatedResponse);

}
else
{
responseHTML = QString(responseBytes);
}

I have no idea why it does not work. I'm really desperate :(

squidge
27th November 2009, 21:29
You seem to be prepending the size of the compressed file (responseBytes.size()), rather than the expected uncompressed size. That seems meaningless to me - if quncompress wants that size, it can just call size() itself.

ricky92
27th November 2009, 22:38
Hmm, you're right. I forgot it's the expected size that it asks for. So now, my question is another: how do I get the expected size from a gzipped string?

squidge
27th November 2009, 23:09
Considering it's just compressed data, you can't. You have to get it from somewhere else. Whoever sent you the data must know the uncompressed size, and they should send it to you.

ricky92
28th November 2009, 00:04
Considering it's just compressed data, you can't. You have to get it from somewhere else. Whoever sent you the data must know the uncompressed size, and they should send it to you.
Hmm 0.o
I'm just trying to decompress a string that contains HTML code of a webpage, and it's the server which compresses it into a gzip stream... I mean, browsers do that as well, so there must be a way. Maybe I have to use native zlib functions...?

squidge
28th November 2009, 12:25
Did you check HTTP Response Headers? I'd be suprised if the decompressed size isn't stored in there.

Another way around the problem is simply to tell the server you don't support compressed HTML.

ricky92
1st December 2009, 17:52
HTTP headers do not send any info on uncompressed size, sadly :(
I have no idea how to solve this problem... I even tried using some zlib methods I found over the web, but I failed. Could anybody help me? I'd be willing to pay for help

squidge
1st December 2009, 18:03
Are you supporting gzip for a reason, or just because the server is sending data to you in that format?

I'm thinking the easiest way to go is to set your "Accept-Encoding" header to exclude compress and gzip, then the server will not compress it in the first place.

ricky92
1st December 2009, 19:36
I'm supporting it because I need my application to be as quick as possible, actually. It's not really needed, but when it comes to downloading html webpages gzip compression can save a lot of bandwidth/time.
And also, it's something I want to undestand for my personal knowledge. It's the first time I'm messing with HTTP compression without some easy module or class (it wasn't too hard in vb.net)