Remove support for parallel requests

This commit is contained in:
Zach Borboa
2015-02-09 01:48:32 -08:00
parent b2f89626fe
commit 2e8ccceae3
2 changed files with 35 additions and 266 deletions
+35 -110
View File
@@ -11,8 +11,6 @@ class Curl
private $headers = array();
private $options = array();
private $multi_parent = false;
private $multi_child = false;
private $before_send_function = null;
private $success_function = null;
private $error_function = null;
@@ -23,7 +21,6 @@ class Curl
private $xml_pattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i';
public $curl;
public $curls;
public $error = false;
public $error_code = 0;
@@ -59,70 +56,14 @@ class Curl
$this->headers = new CaseInsensitiveArray();
}
public function get($url_mixed, $data = array())
public function get($url, $data = array())
{
if (is_array($url_mixed)) {
$curl_multi = curl_multi_init();
$this->multi_parent = true;
$this->curls = array();
foreach ($url_mixed as $url) {
$curl = new Curl();
$curl->multi_child = true;
$curl->beforeSend($this->before_send_function);
$curl->success($this->success_function);
$curl->error($this->error_function);
$curl->complete($this->complete_function);
$curl->base_url = $url;
$curl->url = $this->buildURL($url, $data);
$curl->setOpt(CURLOPT_URL, $curl->url, $curl->curl);
$curl->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
$curl->setOpt(CURLOPT_HTTPGET, true);
$this->curls[] = $curl;
$curlm_error_code = curl_multi_add_handle($curl_multi, $curl->curl);
if (!($curlm_error_code === CURLM_OK)) {
throw new \ErrorException('cURL multi add handle error: ' . curl_multi_strerror($curlm_error_code));
}
}
foreach ($this->curls as $ch) {
foreach ($this->options as $key => $value) {
$ch->setOpt($key, $value);
}
}
do {
curl_multi_select($curl_multi);
$status = curl_multi_exec($curl_multi, $active);
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
while (!($info_array = curl_multi_info_read($curl_multi)) === false) {
if (!($info_array['msg'] === CURLMSG_DONE)) {
continue;
}
foreach ($this->curls as $ch) {
if ($ch->curl === $info_array['handle']) {
$ch->curl_error_code = $info_array['result'];
break;
}
}
}
foreach ($this->curls as $ch) {
$this->exec($ch);
}
} else {
$this->base_url = $url_mixed;
$this->url = $this->buildURL($url_mixed, $data);
$this->setOpt(CURLOPT_URL, $this->url);
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
$this->setOpt(CURLOPT_HTTPGET, true);
return $this->exec();
}
$this->base_url = $url;
$this->url = $this->buildURL($url, $data);
$this->setOpt(CURLOPT_URL, $this->url);
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
$this->setOpt(CURLOPT_HTTPGET, true);
return $this->exec();
}
public function post($url, $data = array())
@@ -306,10 +247,8 @@ class Curl
$this->setOpt(CURLOPT_COOKIEJAR, $cookie_jar);
}
public function setOpt($option, $value, $_ch = null)
public function setOpt($option, $value)
{
$ch = $_ch === null ? $this->curl : $_ch;
$required_options = array(
CURLINFO_HEADER_OUT => 'CURLINFO_HEADER_OUT',
CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
@@ -320,7 +259,7 @@ class Curl
}
$this->options[$option] = $value;
return curl_setopt($ch, $option, $value);
return curl_setopt($this->curl, $option, $value);
}
public function getOpt($option)
@@ -335,12 +274,6 @@ class Curl
public function close()
{
if ($this->multi_parent) {
foreach ($this->curls as $curl) {
$curl->close();
}
}
if (is_resource($this->curl)) {
curl_close($this->curl);
}
@@ -493,67 +426,59 @@ class Curl
protected function exec($_ch = null)
{
$ch = $_ch === null ? $this : $_ch;
$ch->call($this->before_send_function, $ch);
$this->call($this->before_send_function);
$response_headers_fh = fopen('php://memory', 'wb+');
// Fallback to storing data in a temporary file when storing data in
// memory errors with "Warning: curl_setopt(): cannot represent a stream
// of type MEMORY as a STDIO FILE*".
if (!@$ch->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh)) {
if (!@$this->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh)) {
$response_headers_fh = fopen('php://temp', 'wb+');
$ch->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh);
$this->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh);
}
if ($ch->multi_child) {
$ch->raw_response = curl_multi_getcontent($ch->curl);
} else {
$ch->raw_response = curl_exec($ch->curl);
$ch->curl_error_code = curl_errno($ch->curl);
}
$this->raw_response = curl_exec($this->curl);
$this->curl_error_code = curl_errno($this->curl);
rewind($response_headers_fh);
$ch->raw_response_headers = stream_get_contents($response_headers_fh);
$this->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);
$ch->http_error = in_array(floor($ch->http_status_code / 100), array(4, 5));
$ch->error = $ch->curl_error || $ch->http_error;
$ch->error_code = $ch->error ? ($ch->curl_error ? $ch->curl_error_code : $ch->http_status_code) : 0;
$this->curl_error_message = curl_error($this->curl);
$this->curl_error = !($this->curl_error_code === 0);
$this->http_status_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
$this->http_error = in_array(floor($this->http_status_code / 100), array(4, 5));
$this->error = $this->curl_error || $this->http_error;
$this->error_code = $this->error ? ($this->curl_error ? $this->curl_error_code : $this->http_status_code) : 0;
$ch->request_headers = $this->parseRequestHeaders(curl_getinfo($ch->curl, CURLINFO_HEADER_OUT));
$ch->response_headers = $this->parseResponseHeaders($ch->raw_response_headers);
list($ch->response, $ch->raw_response) = $this->parseResponse($ch->response_headers, $ch->raw_response);
$this->request_headers = $this->parseRequestHeaders(curl_getinfo($this->curl, CURLINFO_HEADER_OUT));
$this->response_headers = $this->parseResponseHeaders($this->raw_response_headers);
list($this->response, $this->raw_response) = $this->parseResponse($this->response_headers, $this->raw_response);
$ch->http_error_message = '';
if ($ch->error) {
if (isset($ch->response_headers['Status-Line'])) {
$ch->http_error_message = $ch->response_headers['Status-Line'];
$this->http_error_message = '';
if ($this->error) {
if (isset($this->response_headers['Status-Line'])) {
$this->http_error_message = $this->response_headers['Status-Line'];
}
}
$ch->error_message = $ch->curl_error ? $ch->curl_error_message : $ch->http_error_message;
$this->error_message = $this->curl_error ? $this->curl_error_message : $this->http_error_message;
if (!$ch->error) {
$ch->call($this->success_function, $ch);
if (!$this->error) {
$this->call($this->success_function);
} else {
$ch->call($this->error_function, $ch);
$this->call($this->error_function);
}
$ch->call($this->complete_function, $ch);
$this->call($this->complete_function);
return $ch->response;
return $this->response;
}
private function call($function)
{
if (is_callable($function)) {
$args = func_get_args();
array_shift($args);
call_user_func_array($function, $args);
call_user_func_array($function, array($this));
}
}
-156
View File
@@ -887,89 +887,6 @@ class CurlTest extends PHPUnit_Framework_TestCase
$this->assertEquals('foo=bar&baz[qux]=&baz[wibble]=wobble', urldecode($test->curl->response));
}
public function testParallelRequests()
{
$test = new Test();
$curl = $test->curl;
$curl->setHeader('X-DEBUG-TEST', 'request_uri');
$curl->get(array(
Test::TEST_URL . 'a/',
Test::TEST_URL . 'b/',
Test::TEST_URL . 'c/',
), array(
'foo' => 'bar',
));
$len = strlen('/a/?foo=bar');
$this->assertEquals('/a/?foo=bar', substr($curl->curls['0']->response, - $len));
$this->assertEquals('/b/?foo=bar', substr($curl->curls['1']->response, - $len));
$this->assertEquals('/c/?foo=bar', substr($curl->curls['2']->response, - $len));
}
public function testParallelRequestErrors()
{
$test = new Test();
$curl = $test->curl;
$curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 4000);
$curl->complete(function ($instance) use (&$success_called, &$error_called, &$complete_called) {
PHPUnit_Framework_Assert::assertTrue($instance->error);
PHPUnit_Framework_Assert::assertTrue($instance->curl_error);
PHPUnit_Framework_Assert::assertEquals(CURLE_OPERATION_TIMEOUTED, $instance->error_code);
PHPUnit_Framework_Assert::assertEquals(CURLE_OPERATION_TIMEOUTED, $instance->curl_error_code);
});
$curl->get(array(
Test::ERROR_URL . 'a/',
Test::ERROR_URL . 'b/',
Test::ERROR_URL . 'c/',
));
}
public function testParallelSetOptions()
{
$test = new Test();
$curl = $test->curl;
$curl->setHeader('X-DEBUG-TEST', 'server');
$curl->setOpt(CURLOPT_USERAGENT, 'useragent');
$curl->complete(function ($instance) {
PHPUnit_Framework_Assert::assertEquals('useragent', $instance->response);
});
$curl->get(array(
Test::TEST_URL,
), array(
'key' => 'HTTP_USER_AGENT',
));
}
public function testParallelUrl()
{
$data = array('foo' => 'bar');
$test = new Test();
$curl = $test->curl;
$curl->setHeader('X-DEBUG-TEST', 'server');
$curl->complete(function ($instance) use ($data) {
PHPUnit_Framework_Assert::assertEquals(Test::TEST_URL, $instance->base_url);
PHPUnit_Framework_Assert::assertEquals(Test::TEST_URL . '?' . http_build_query($data), $instance->url);
});
$curl->get(array(
Test::TEST_URL,
), $data);
}
public function testParallelGetOptions()
{
$test = new Test();
$curl = $test->curl;
$curl->setHeader('X-DEBUG-TEST', 'server');
$curl->setOpt(CURLOPT_USERAGENT, 'useragent');
$curl->complete(function ($instance) {
PHPUnit_Framework_Assert::assertEquals('useragent', $instance->getOpt(CURLOPT_USERAGENT));
});
$curl->get(array(
Test::TEST_URL,
));
}
public function testSuccessCallback()
{
$before_send_called = false;
@@ -1020,79 +937,6 @@ class CurlTest extends PHPUnit_Framework_TestCase
$this->assertTrue($complete_called);
}
public function testParallelSuccessCallback()
{
$success_called = false;
$error_called = false;
$complete_called = false;
$success_called_once = false;
$error_called_once = false;
$complete_called_once = false;
$test = new Test();
$curl = $test->curl;
$curl->setHeader('X-DEBUG-TEST', 'get');
$curl->success(function ($instance) use (
&$success_called,
&$error_called,
&$complete_called,
&$success_called_once
) {
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
PHPUnit_Framework_Assert::assertFalse($success_called);
PHPUnit_Framework_Assert::assertFalse($error_called);
PHPUnit_Framework_Assert::assertFalse($complete_called);
$success_called = true;
$success_called_once = true;
});
$curl->error(function ($instance) use (
&$success_called,
&$error_called,
&$complete_called,
&$curl,
&$error_called_once
) {
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
PHPUnit_Framework_Assert::assertFalse($success_called);
PHPUnit_Framework_Assert::assertFalse($error_called);
PHPUnit_Framework_Assert::assertFalse($complete_called);
$error_called = true;
$error_called_once = true;
});
$curl->complete(function ($instance) use (
&$success_called,
&$error_called,
&$complete_called,
&$complete_called_once
) {
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
PHPUnit_Framework_Assert::assertTrue($success_called);
PHPUnit_Framework_Assert::assertFalse($error_called);
PHPUnit_Framework_Assert::assertFalse($complete_called);
$complete_called = true;
$complete_called_once = true;
PHPUnit_Framework_Assert::assertTrue($success_called);
PHPUnit_Framework_Assert::assertFalse($error_called);
PHPUnit_Framework_Assert::assertTrue($complete_called);
$success_called = false;
$error_called = false;
$complete_called = false;
});
$curl->get(array(
Test::TEST_URL . 'a/',
Test::TEST_URL . 'b/',
Test::TEST_URL . 'c/',
));
$this->assertTrue($success_called_once || $error_called_once);
$this->assertTrue($complete_called_once);
}
public function testErrorCallback()
{
$before_send_called = false;