tags:

views:

34

answers:

2

If I execute a cURL request that is set to follow redirects and return the headers, it returns the headers for ALL of the redirects.

I only want the last header returned (and the content body). How do I achieve that?

+1  A: 

Search the output for "HTTP/1.1 200 OK" in the beginning of the line - this is where your last request will begin. All others will give other HTTP return codes.

m1tk4
Ah. Great idea. Thanks!
George Edison
One thing though - what about HTTP 1.0? And is 'OK' a standard message after the 200?
George Edison
I'd use something like preg_match('/^HTTP 1\.[01] 200/'... to be sure. Good point on HTTP 1.0. OK is a de-facto standard, however the RFC only specifies the result number (200).
m1tk4
A: 

Here's another way:

$url = 'http://google.com';

$opts = array(CURLOPT_RETURNTRANSFER => true,
              CURLOPT_FOLLOWLOCATION => true,
              CURLOPT_HEADER         => true);
$ch = curl_init($url);
curl_setopt_array($ch, $opts);
$response       = curl_exec($ch);
$redirect_count = curl_getinfo($ch, CURLINFO_REDIRECT_COUNT);
$status         = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$response       = explode("\r\n\r\n", $response, $redirect_count + 2);
$last_header    = $response[$redirect_count];
if ($status == '200') {
    $body = end($response);
} else {
    $body = '';
}
curl_close($ch);

echo '<pre>';
echo 'Redirects: ' . $redirect_count . '<br />';
echo 'Status: ' . $status . '<br />';
echo 'Last response header:<br />' . $last_header . '<br />';
echo 'Response body:<br />' . htmlspecialchars($body) . '<br />';
echo '</pre>';

Of course, you'll need more error checking, such as for timeout, etc.

GZipp
What happens if one of the redirect response bodies contains an extra \r\n\r\n?
m1tk4
What I ended up doing was just following the redirects myself by looping on 301 and 302 responses.
George Edison
@m1tkr - That's why the call to explode() contains the limiting argument ($redirect_count + 2).
GZipp
@George Edison - That'll work, I'm sure, but with the code I posted you keep all the headers plus the content in one neat array.
GZipp
@m1tk4 - After re-reading, I see what you're getting at. I don't believe (but don't know for sure) that any webserver will send a body with a redirect response (tested with IIS and Apache only). Otherwise it's something that would need to be checked for in actual, non-demo, code.
GZipp
@m1tk4 - And, after more testing (with Wireshark), I see that a body, if there is one, is sent, but that curl discards it. So my code works as posted.
GZipp