mirror of
https://github.com/php-curl-class/php-curl-class.git
synced 2026-08-30 12:14:36 +00:00
Write response headers to a stream resource and make CURLOPT_HEADER optional
This commit is contained in:
+33
-36
@@ -48,7 +48,6 @@ class Curl
|
||||
$this->curl = curl_init();
|
||||
$this->setDefaultUserAgent();
|
||||
$this->setOpt(CURLINFO_HEADER_OUT, true);
|
||||
$this->setOpt(CURLOPT_HEADER, true);
|
||||
$this->setOpt(CURLOPT_RETURNTRANSFER, true);
|
||||
}
|
||||
|
||||
@@ -247,7 +246,6 @@ class Curl
|
||||
|
||||
$required_options = array(
|
||||
CURLINFO_HEADER_OUT => 'CURLINFO_HEADER_OUT',
|
||||
CURLOPT_HEADER => 'CURLOPT_HEADER',
|
||||
CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
|
||||
);
|
||||
|
||||
@@ -338,49 +336,40 @@ class Curl
|
||||
return $request_headers;
|
||||
}
|
||||
|
||||
private function parseResponse($response)
|
||||
private function parseResponse($response_headers, $raw_response)
|
||||
{
|
||||
$response_headers = '';
|
||||
$raw_response = $response;
|
||||
if (!(strpos($response, "\r\n\r\n") === false)) {
|
||||
$response_array = explode("\r\n\r\n", $response);
|
||||
$response_header = '';
|
||||
for ($i = count($response_array) - 1; $i >= 0; $i--) {
|
||||
if (stripos($response_array[$i], 'HTTP/') === 0) {
|
||||
$response_header = $response_array[$i];
|
||||
$response = implode("\r\n\r\n", array_splice($response_array, $i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
$response_headers = explode("\r\n", $response_header);
|
||||
if (in_array('HTTP/1.1 100 Continue', $response_headers)) {
|
||||
list($response_header, $response) = explode("\r\n\r\n", $response, 2);
|
||||
}
|
||||
$response_headers = $this->parseResponseHeaders($response_header);
|
||||
$raw_response = $response;
|
||||
|
||||
if (isset($response_headers['Content-Type'])) {
|
||||
if (preg_match('~^application/(?:json|vnd\.api\+json)~i', $response_headers['Content-Type'])) {
|
||||
$json_obj = json_decode($response, false);
|
||||
if ($json_obj !== null) {
|
||||
$response = $json_obj;
|
||||
}
|
||||
} elseif (preg_match('~^(?:text/|application/(?:atom\+|rss\+)?)xml~i', $response_headers['Content-Type'])) {
|
||||
$xml_obj = @simplexml_load_string($response);
|
||||
if (!($xml_obj === false)) {
|
||||
$response = $xml_obj;
|
||||
}
|
||||
$response = $raw_response;
|
||||
if (isset($response_headers['Content-Type'])) {
|
||||
if (preg_match('~^application/(?:json|vnd\.api\+json)~i', $response_headers['Content-Type'])) {
|
||||
$json_obj = json_decode($response, false);
|
||||
if ($json_obj !== null) {
|
||||
$response = $json_obj;
|
||||
}
|
||||
} elseif (preg_match('~^(?:text/|application/(?:atom\+|rss\+)?)xml~i', $response_headers['Content-Type'])) {
|
||||
$xml_obj = @simplexml_load_string($response);
|
||||
if (!($xml_obj === false)) {
|
||||
$response = $xml_obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array($response_headers, $response, $raw_response);
|
||||
return array($response, $raw_response);
|
||||
}
|
||||
|
||||
private function parseResponseHeaders($raw_headers)
|
||||
private function parseResponseHeaders($raw_response_headers)
|
||||
{
|
||||
$response_header_array = explode("\r\n\r\n", $raw_response_headers);
|
||||
$response_header = '';
|
||||
for ($i = count($response_header_array) - 1; $i >= 0; $i--) {
|
||||
if (stripos($response_header_array[$i], 'HTTP/') === 0) {
|
||||
$response_header = $response_header_array[$i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$response_headers = new CaseInsensitiveArray();
|
||||
list($first_line, $headers) = $this->parseHeaders($raw_headers);
|
||||
list($first_line, $headers) = $this->parseHeaders($response_header);
|
||||
$response_headers['Status-Line'] = $first_line;
|
||||
foreach ($headers as $key => $value) {
|
||||
$response_headers[$key] = $value;
|
||||
@@ -427,6 +416,9 @@ class Curl
|
||||
{
|
||||
$ch = $_ch === null ? $this : $_ch;
|
||||
|
||||
$response_headers_fh = fopen('php://memory', 'wb+');
|
||||
$ch->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh);
|
||||
|
||||
if ($ch->multi_child) {
|
||||
$ch->raw_response = curl_multi_getcontent($ch->curl);
|
||||
} else {
|
||||
@@ -434,6 +426,10 @@ class Curl
|
||||
$ch->curl_error_code = curl_errno($ch->curl);
|
||||
}
|
||||
|
||||
rewind($response_headers_fh);
|
||||
$ch->raw_response_headers = stream_get_contents($response_headers_fh);
|
||||
fclose($response_headers_fh);
|
||||
|
||||
$ch->curl_error_message = curl_error($ch->curl);
|
||||
$ch->curl_error = !($ch->curl_error_code === 0);
|
||||
$ch->http_status_code = curl_getinfo($ch->curl, CURLINFO_HTTP_CODE);
|
||||
@@ -442,7 +438,8 @@ class Curl
|
||||
$ch->error_code = $ch->error ? ($ch->curl_error ? $ch->curl_error_code : $ch->http_status_code) : 0;
|
||||
|
||||
$ch->request_headers = $this->parseRequestHeaders(curl_getinfo($ch->curl, CURLINFO_HEADER_OUT));
|
||||
list($ch->response_headers, $ch->response, $ch->raw_response) = $this->parseResponse($ch->raw_response);
|
||||
$ch->response_headers = $this->parseResponseHeaders($ch->raw_response_headers);
|
||||
list($ch->response, $ch->raw_response) = $this->parseResponse($ch->response_headers, $ch->raw_response);
|
||||
|
||||
$ch->http_error_message = '';
|
||||
if ($ch->error) {
|
||||
|
||||
@@ -147,7 +147,7 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
)));
|
||||
}
|
||||
|
||||
public function testPostContinueResponse()
|
||||
public function testPostContinueResponseHeader()
|
||||
{
|
||||
// 100 Continue responses may contain additional optional headers per
|
||||
// RFC 2616, Section 10.1:
|
||||
@@ -167,18 +167,16 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
'Content-Type: text/plain;charset=UTF-8' . "\r\n" .
|
||||
'Server: PHP-Curl-Class' . "\r\n" .
|
||||
'Connection: keep-alive' . "\r\n" .
|
||||
"\r\n" .
|
||||
'OK';
|
||||
"\r\n";
|
||||
|
||||
$reflector = new ReflectionClass('\Curl\Curl');
|
||||
$reflection_method = $reflector->getMethod('parseResponse');
|
||||
$reflection_method = $reflector->getMethod('parseResponseHeaders');
|
||||
$reflection_method->setAccessible(true);
|
||||
|
||||
$curl = new Curl();
|
||||
list($response_headers, $response) = $reflection_method->invoke($curl, $response);
|
||||
$response_headers = $reflection_method->invoke($curl, $response);
|
||||
|
||||
$this->assertEquals('HTTP/1.1 200 OK', $response_headers['Status-Line']);
|
||||
$this->assertEquals('OK', $response);
|
||||
}
|
||||
|
||||
public function testPostData()
|
||||
@@ -721,7 +719,7 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
$response = "\r\n\r\n";
|
||||
|
||||
$reflector = new ReflectionClass('\Curl\Curl');
|
||||
$reflection_method = $reflector->getMethod('parseResponse');
|
||||
$reflection_method = $reflector->getMethod('parseResponseHeaders');
|
||||
$reflection_method->setAccessible(true);
|
||||
|
||||
$curl = new Curl();
|
||||
@@ -1029,15 +1027,6 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
$curl->setOpt(CURLINFO_HEADER_OUT, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException PHPUnit_Framework_Error_Warning
|
||||
*/
|
||||
public function testRequiredOptionCurlOptHeaderEmitsWarning()
|
||||
{
|
||||
$curl = new Curl();
|
||||
$curl->setOpt(CURLOPT_HEADER, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException PHPUnit_Framework_Error_Warning
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user