简体   繁体   中英

Curl response headers on error

I'm working on PHP client for my API and I'm using Curl to do the request. All goes well but when there is a response http code of 400 or higher I can't seem to get the headers from the response.

To get the headers from all responses is needed because my API adds an extra header to the response with more information about what went wrong.

If there a way to always get the headers from the response in Curl?

    $ch = curl_init();

    // Convert headers to curlopts
    $headers_new = array();
    foreach($headers as $key => $value){
        if(isset($this->_header_to_curlopt[$key])){
            switch($key) {
                case self::HEADER_AUTHORIZATION:
                    if(strstr($value, 'Basic')) {
                        $value = base64_decode(trim(str_replace('Basic ', '', $value)));
                    }
                    break;
                case self::HEADER_COOKIE:
                    if(is_array($value)) {
                        $value = $this->cookieStringToArray($value);
                    }
                    break;
            }
            curl_setopt($ch, $this->_header_to_curlopt[$key], $value);
            unset($this->_requestHeaders[$key]);
        }else{
            $headers_new[] = $key . ': ' . $value;
        }
    }
    $headers = $headers_new;

    // Add length header if it is not set
    if(!isset($headers[self::HEADER_CONTENT_LENGTH])){
        if(is_array($data)) {
            $headers[self::HEADER_CONTENT_LENGTH] = strlen(http_build_query($data, '', '&'));
        } else {
            $headers[self::HEADER_CONTENT_LENGTH] = strlen($data);
        }
    }

    // Set headers
    if(count($headers)){
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        // Don't output content
    curl_setopt($ch ,CURLOPT_TIMEOUT, $timeout);        // Timeout

    switch($method){
        case self::METHOD_POST:
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            break;
        case self::METHOD_GET:
            if(count($this->_data)) {
                $separator = strstr($url, '?') ? '&' : '?';
                $url .= $separator . http_build_query($this->_data, '', '&');
            }
            break;
        default:
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
            break;
    }

    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);

    // Use SSL
    if(strtolower(substr($url, 0, 5)) == 'https') {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    }
    $result = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    // Separate content and headers
    $result = str_replace("\r\n\r\nHTTP/", "\r\nHTTP/", $result);
    $parts = explode("\r\n\r\n",$result);
    $headers = array_shift($parts);
    $result = implode("\r\n\r\n", $parts);

You should set the CURLOPT_HEADER flag, you can get the HTTP status code using curl_getinfo .

<?php 
$ch = curl_init('http://yoururl/'); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
$c = curl_exec($ch); 
echo curl_getinfo($ch, CURLINFO_HTTP_CODE);

from your code

$ch = curl_init();

// Convert headers to curlopts
$headers_new = array();
foreach($headers as $key => $value){
    if(isset($this->_header_to_curlopt[$key])){
        switch($key) {
            case self::HEADER_AUTHORIZATION:
                if(strstr($value, 'Basic')) {
                    $value = base64_decode(trim(str_replace('Basic ', '', $value)));
                }
                break;
            case self::HEADER_COOKIE:
                if(is_array($value)) {
                    $value = $this->cookieStringToArray($value);
                }
                break;
        }
        curl_setopt($ch, $this->_header_to_curlopt[$key], $value);
        unset($this->_requestHeaders[$key]);
    }else{
        $headers_new[] = $key . ': ' . $value;
    }
}
$headers = $headers_new;
curl_setopt($ch, CURLOPT_HEADER, 1); 
// Add length header if it is not set
if(!isset($headers[self::HEADER_CONTENT_LENGTH])){
    if(is_array($data)) {
        $headers[self::HEADER_CONTENT_LENGTH] = strlen(http_build_query($data, '', '&'));
    } else {
        $headers[self::HEADER_CONTENT_LENGTH] = strlen($data);
    }
}

// Set headers
if(count($headers)){
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        // Don't output content
curl_setopt($ch ,CURLOPT_TIMEOUT, $timeout);        // Timeout

switch($method){
    case self::METHOD_POST:
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        break;
    case self::METHOD_GET:
        if(count($this->_data)) {
            $separator = strstr($url, '?') ? '&' : '?';
            $url .= $separator . http_build_query($this->_data, '', '&');
        }
        break;
    default:
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
        break;
}

curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);

// Use SSL
if(strtolower(substr($url, 0, 5)) == 'https') {
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
$result = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Separate content and headers
$result = str_replace("\r\n\r\nHTTP/", "\r\nHTTP/", $result);
$parts = explode("\r\n\r\n",$result);
$headers = array_shift($parts);
$result = implode("\r\n\r\n", $parts);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM