1

When I run curl -I http://api.stackoverflow.com/1.1/badges fro my terminal, it shows me the following headers:

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 42804
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
X-AspNetMvc-Version: 4.0
X-RateLimit-Max: 300
X-RateLimit-Current: 297
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXBrowserOverride=; expires=Mon, 08-Oct-2012 04:29:28 GMT; path=/
Date: Tue, 09 Oct 2012 04:29:27 GMT

Yet, when I run the same cURL request through PHP, I get this:

Array
(
    [url] => http://api.stackoverflow.com/1.1/badges?10102
    [content_type] => application/json; charset=utf-8
    [http_code] => 200
    [header_size] => 277
    [request_size] => 85
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.168343
    [namelookup_time] => 0.023417
    [connect_time] => 0.046293
    [pretransfer_time] => 0.046365
    [size_upload] => 0
    [size_download] => 42804
    [speed_download] => 254266
    [speed_upload] => 0
    [download_content_length] => 42804
    [upload_content_length] => 0
    [starttransfer_time] => 0.097563
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [redirect_url] => 
)

The major difference that matters to me is that when run through PHP, I do not get the Content-Encoding header, without which I do not know if the content needs to be gzip inflated or not.

Is there a way to get the Content-Encoding header, or to check for gzip compression some other way?

2 Answers 2

6

There is no header_response nor accept-encoding in the returned getinfo array. I thought CURLINFO_HEADER_OUT on getinfo would give response headers, but only request headers are given.

But you can get raw headers using the CURLOPT_HEADER option set to true. So I suggest you to do something less natural :

$curl = curl_init();

$opts = array (
        CURLOPT_URL => 'http://api.stackoverflow.com/1.1/badges',
        CURLOPT_TIMEOUT => 120,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_ENCODING => 'gzip',
        CURLOPT_HEADER => true,
);
curl_setopt_array($curl, $opts);

$return = curl_exec($curl);

list($rawHeader, $response) = explode("\r\n\r\n", $return, 2);

$cutHeaders = explode("\r\n", $rawHeader);
$headers = array();
foreach ($cutHeaders as $row)
{
    $cutRow = explode(":", $row, 2);
    $headers[$cutRow[0]] = trim($cutRow[1]);
}

echo $headers['Content-Encoding']; // gzip
Sign up to request clarification or add additional context in comments.

Comments

3

If you set CURLOPT_HEADER to true, curl returns the header alongside the body. If you're just interested in the header, you can set CURLOPT_NOBODY to true and the body is not returned (which emulates the -I flag on the command line).

This example sets just the CURLOPT_HEADER, reads the Content-Encoding header (if it is set) and uncompresses the body:

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, "http://api.stackoverflow.com/1.1/badges");
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($curl);
curl_close($curl);

list($header, $body) = explode("\r\n\r\n", $response, 2);
if(preg_match('@Content-Encoding:\s+(\w+)@i', $header, $match)) {
    switch (strtolower($match[1])) {
        case 'gzip':
            $body = gzdecode($body);
        break;

        case 'compress':
            $body = gzuncompress($body);
        break;

        case 'deflate':
            $body = gzdeflate($body);
        break;
    }
}
echo $header;
echo $body;

Disclaimer: gzdecode might not be available in your PHP-version. I've tested it with PHP 5.4.4 and it worked.

You could also install the HTTP_Request2-PEAR package which does that for you (plus you get easy access to the headers without HTTP-header parsing):

include 'HTTP/Request2.php';
$request  = new HTTP_Request2('http://api.stackoverflow.com/1.1/badges',
    HTTP_Request2::METHOD_GET);

$response = $request->send();

echo $response->getBody();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.