34

Does anyone know how to uncompress the contents of a gzip file that i got with curl?

for example: http://torcache.com/torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent

responded

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 09 Jun 2010 01:11:26 GMT
Content-Type: application/x-bittorrent
Content-Length: 52712
Last-Modified: Tue, 08 Jun 2010 15:09:58 GMT
Connection: keep-alive
Expires: Fri, 09 Jul 2010 01:11:26 GMT
Cache-Control: max-age=2592000
Content-Encoding: gzip
Accept-Ranges: bytes

then the compressed gzip,

i tried gzdecode but doesn't work , gzeflate as well doesn't they simply don't get any response, and the contents of the files are no more than 2k

Daniel Stenberg
  • 54,736
  • 17
  • 146
  • 222
PartySoft
  • 2,749
  • 7
  • 39
  • 55

7 Answers7

87

Just tell cURL to decode the response automatically whenever it's gzipped

curl_setopt($ch,CURLOPT_ENCODING, '');
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
mixdev
  • 2,724
  • 2
  • 30
  • 25
18

Use gzdecode:

<?php
    $c = file_get_contents("http://torcache.com/" .
        "torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent");
    echo gzdecode($c);

gives

d8:announce42:http://tracker.openbittorrent.com/announce13:announce-listll42
...
Artefacto
  • 96,375
  • 17
  • 202
  • 225
  • 3
    yes true, but I have php 5.2, and they say that gzdecode is available since 6.0 only I have a gentoo with php and zlib configured , and i can't seem to have available those gz functions. Any ideeas? :) – PartySoft Jun 09 '10 at 15:13
  • 6
    Ok, i have a solution , no pretty because i had to write to a file the contents, and not only use a string : function gzdecode($data){ $g=tempnam('/tmp','ff'); @file_put_contents($g,$data); ob_start(); readgzfile($g); $d=ob_get_clean(); unlink($g); return $d; } and it works :) – PartySoft Jun 09 '10 at 15:27
  • @PartySoft That function is great! – barfoon Oct 21 '11 at 20:48
  • @PartySoft Thanks for that! Worked like a charm. Running 5.3.X and had no luck with [gzuncompress()](http://www.php.net/manual/en/function.gzuncompress.php). – donut Mar 17 '14 at 22:09
  • I suggest to use the $length parameter as it guards your script of insufficient memory errors. For example `$contents = gzdecode($contents, 10485760);` will stop decompression if the result will be more than 10 MB. I had several websites that were < 1 MB in gzipped size and after `gzdecode()` they raised to 30 MB! If you prefer CURLOPT_ENCODING you should try CURLOPT_WRITEFUNCTION if you are able stop the decompression result by that as well. I did not test it. – mgutt Apr 14 '15 at 11:37
  • 1
    what the heck, no, just set CURLOPT_ENCODING to "gzip" and curl will automatically decompress gzip-encoded responses – hanshenrik Jun 25 '19 at 09:58
13

libcurl offers a feature that makes it decompress the contents automatically (if built with zlib).

See the CURLOPT_ACCEPT_ENCODING option: https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html

mbomb007
  • 3,788
  • 3
  • 39
  • 68
Daniel Stenberg
  • 54,736
  • 17
  • 146
  • 222
1

Have you tried setting the header stating that you accept gzip encoding as follows?:

curl_setopt($rCurl, CURLOPT_HTTPHEADER, array('Accept-Encoding: gzip,deflate'));
Oren Hizkiya
  • 4,420
  • 2
  • 23
  • 33
  • 4
    he's already receiving it encoded, so I don't think declaring that he accepts it encoded would do any difference. I tried sending the server Accept-encoding: none and the server did not comply. – Artefacto Jun 09 '10 at 01:59
1

With a zlib Stream Wrapper:

file_get_contents("compress.zlib://http://torcache.com/" .
    "torrent/63ABC1435AA5CD48DCD866C6F7D5E80766034391.torrent");
Gordon
  • 312,688
  • 75
  • 539
  • 559
0

Have you tried gzuncompress or gzinflate?

gzdeflate compresses, the opposite of what you want. To be honest, I can't figure out how gzdecode differs from normal uncompressing.

There's also the cURL option CURLOPT_ENCODING:

The contents of the "Accept-Encoding: " header. This enables decoding of the response. Supported encodings are "identity", "deflate", and "gzip". If an empty string, "", is set, a header containing all supported encoding types is sent.

It seems to mean it'll automatically decompress the response, but I haven't tested that.

deceze
  • 510,633
  • 85
  • 743
  • 889
0

You can do it with gzinflate (pretending that $headers contains all your HTTP headers, and $buffer contains your data):

if (isset($headers['Content-Encoding']) && ($headers['Content-Encoding'] === 'gzip' || $headers['Content-Encoding'] === 'deflate'))
    {
        if ($headers['Content-Encoding'] === 'gzip')
        {
            $buffer = substr($buffer, 10);
        }
        $contents = @gzinflate($buffer);
        if ($contents === false)
        {
            return false;
        }
    }
Yvan
  • 2,539
  • 26
  • 28