Avoids calculating header size in curl responses (#677)

- Removes complex conditions around parsing response headers
This commit is contained in:
Bryant Luk
2017-05-11 12:53:32 -05:00
committed by Jay
parent 8d157c3233
commit bc139915df

View File

@@ -25,6 +25,16 @@ class PayPalHttpConnection
*/
private $logger;
/**
* @var array
*/
private $responseHeaders = array();
/**
* @var bool
*/
private $skippedHttpStatusLine = false;
/**
* Default Constructor
*
@@ -55,6 +65,57 @@ class PayPalHttpConnection
return $ret;
}
/**
* Parses the response headers for debugging.
*
* @param resource $ch
* @param string $data
* @return int
*/
protected function parseResponseHeaders($ch, $data) {
if (!$this->skippedHttpStatusLine) {
$this->skippedHttpStatusLine = true;
return strlen($data);
}
$trimmedData = trim($data);
if (strlen($trimmedData) == 0) {
return strlen($data);
}
list($key, $value) = explode(":", $trimmedData, 2);
$key = trim($key);
$value = trim($value);
// This will skip over the HTTP Status Line and any other lines
// that don't look like header lines with values
if (strlen($key) > 0 && strlen($value) > 0) {
// This is actually a very basic way of looking at response headers
// and may miss a few repeated headers with different (appended)
// values but this should work for debugging purposes.
$this->responseHeaders[$key] = $value;
}
return strlen($data);
}
/**
* Implodes a key/value array for printing.
*
* @param array $arr
* @return string
*/
protected function implodeArray($arr) {
$retStr = '';
foreach($arr as $key => $value) {
$retStr .= $key . ': ' . $value . ', ';
}
rtrim($retStr, ', ');
return $retStr;
}
/**
* Executes an HTTP request
*
@@ -75,7 +136,7 @@ class PayPalHttpConnection
}
curl_setopt_array($ch, $options);
curl_setopt($ch, CURLOPT_URL, $this->httpConfig->getUrl());
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHttpHeaders());
@@ -97,11 +158,9 @@ class PayPalHttpConnection
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->httpConfig->getMethod());
}
//Logging Each Headers for debugging purposes
foreach ($this->getHttpHeaders() as $header) {
//TODO: Strip out credentials and other secure info when logging.
// $this->logger->debug($header);
}
$this->responseHeaders = array();
$this->skippedHttpStatusLine = false;
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'parseResponseHeaders'));
//Execute Curl Request
$result = curl_exec($ch);
@@ -130,21 +189,10 @@ class PayPalHttpConnection
// Get Request and Response Headers
$requestHeaders = curl_getinfo($ch, CURLINFO_HEADER_OUT);
//Using alternative solution to CURLINFO_HEADER_SIZE as it throws invalid number when called using PROXY.
if (function_exists('mb_strlen')) {
$responseHeaderSize = mb_strlen($result, '8bit') - curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
$responseHeaders = mb_substr($result, 0, $responseHeaderSize, '8bit');
$result = mb_substr($result, $responseHeaderSize, mb_strlen($result), '8bit');
} else {
$responseHeaderSize = strlen($result) - curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
$responseHeaders = substr($result, 0, $responseHeaderSize);
$result = substr($result, $responseHeaderSize);
}
$this->logger->debug("Request Headers \t: " . str_replace("\r\n", ", ", $requestHeaders));
$this->logger->debug(($data && $data != '' ? "Request Data\t\t: " . $data : "No Request Payload") . "\n" . str_repeat('-', 128) . "\n");
$this->logger->info("Response Status \t: " . $httpStatus);
$this->logger->debug("Response Headers\t: " . str_replace("\r\n", ", ", $responseHeaders));
$this->logger->debug("Response Headers\t: " . $this->implodeArray($this->responseHeaders));
//Close the curl request
curl_close($ch);