Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 67 additions & 15 deletions library/core/Curl/Handler.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php
/** @noinspection PhpDuplicateSwitchCaseBodyInspection */

namespace Swoole\Curl;

Expand Down Expand Up @@ -55,6 +56,8 @@ class Handler
private $withFileTime = false;
private $urlInfo;
private $postData;
private $infile;
private $infileSize = PHP_INT_MAX;
private $outputStream;
private $proxy;
private $clientOptions = [];
Expand Down Expand Up @@ -91,13 +94,21 @@ public function __construct($url = null)

private function create(string $url): void
{
if (!swoole_string($url)->contains('://')) {
if (strlen($url) === 0) {
$this->setError(CURLE_URL_MALFORMAT);
return;
}
if (strpos($url, '://') === false) {
$url = 'http://' . $url;
}
$this->info['url'] = $url;
$info = parse_url($url);
if (!is_array($info)) {
$this->setError(CURLE_URL_MALFORMAT, "URL[{$url}] using bad/illegal format");
return;
}
$proto = swoole_array_default_value($info, 'scheme');
if ($proto != 'http' and $proto != 'https') {
if ($proto !== 'http' and $proto !== 'https') {
$this->setError(CURLE_UNSUPPORTED_PROTOCOL, "Protocol \"{$proto}\" not supported or disabled in libcurl");
return;
}
Expand All @@ -120,7 +131,7 @@ public function execute()
* Socket
*/
$client = $this->client;
if (!$client) {
if (!$client || !$this->urlInfo) {
if (!$this->errCode) {
$this->setError(CURLE_URL_MALFORMAT);
}
Expand Down Expand Up @@ -165,6 +176,25 @@ public function execute()
$client->set($this->clientOptions);
}
$client->setMethod($this->method);
/**
* Infile
*/
if ($this->infile) {
$data = '';
while (true) {
$nLength = $this->infileSize - strlen($data);
if ($nLength === 0) {
break;
}
if (feof($this->infile)) {
break;
}
$data .= fread($this->infile, $nLength);
}
$client->setData($data);
$this->infile = null;
$this->infileSize = PHP_INT_MAX;
}
/**
* Upload File
*/
Expand Down Expand Up @@ -339,6 +369,18 @@ private function getUrl(): string
*/
public function setOption(int $opt, $value): bool
{
switch ($opt) {
// case CURLOPT_STDERR:
// case CURLOPT_WRITEHEADER:
case CURLOPT_FILE:
case CURLOPT_INFILE:
if (!is_resource($value)) {
trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): supplied argument is not a valid File-Handle resource');
return false;
}
break;
}

switch ($opt) {
/**
* Basic
Expand Down Expand Up @@ -366,18 +408,18 @@ public function setOption(int $opt, $value): bool
/**
* Ignore options
*/
case CURLOPT_VERBOSE:
// trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): CURLOPT_VERBOSE is not supported');
case CURLOPT_SSLVERSION:
case CURLOPT_NOSIGNAL:
case CURLOPT_FRESH_CONNECT:
/**
* From PHP 5.1.3, this option has no effect: the raw output will always be returned when CURLOPT_RETURNTRANSFER is used.
*/
case CURLOPT_BINARYTRANSFER:
/**
* TODO
*/
case CURLOPT_VERBOSE:
/**
* From PHP 5.1.3, this option has no effect: the raw output will always be returned when CURLOPT_RETURNTRANSFER is used.
*/
case CURLOPT_BINARYTRANSFER: /* TODO */
case CURLOPT_DNS_CACHE_TIMEOUT:
case CURLOPT_STDERR:
case CURLOPT_WRITEHEADER:
break;
/**
* SSL
Expand All @@ -402,7 +444,7 @@ public function setOption(int $opt, $value): bool
*/
case CURLOPT_SAFE_UPLOAD:
if (!$value) {
trigger_error('curl_setopt(): Disabling safe uploads is no longer supported', E_USER_WARNING);
trigger_error('swoole_curl_setopt(): Disabling safe uploads is no longer supported', E_USER_WARNING);
}
break;
/**
Expand Down Expand Up @@ -438,15 +480,16 @@ public function setOption(int $opt, $value): bool
break;

case CURLOPT_CUSTOMREQUEST:
$this->method = (string)$value;
break;
case CURLOPT_PROTOCOLS:
if ($value > 3) {
throw new Swoole\Curl\Exception("option[{$opt}={$value}] not supported");
throw new Swoole\Curl\Exception("swoole_curl_setopt(): CURLOPT_PROTOCOLS[{$value}] is not supported");
}
break;
case CURLOPT_HTTP_VERSION:
if ($value != CURL_HTTP_VERSION_1_1) {
trigger_error("swoole_curl: http version[{$value}] not supported", E_USER_WARNING);
trigger_error("swoole_curl_setopt(): CURLOPT_HTTP_VERSION[{$value}] is not supported", E_USER_WARNING);
}
break;
/**
Expand Down Expand Up @@ -497,8 +540,17 @@ public function setOption(int $opt, $value): bool
case CURLOPT_MAXREDIRS:
$this->maxRedirs = $value;
break;
case CURLOPT_PUT:
$this->method = 'PUT';
break;
case CURLOPT_INFILE:
$this->infile = $value;
break;
case CURLOPT_INFILESIZE:
$this->infileSize = $value;
break;
default:
throw new Swoole\Curl\Exception("option[{$opt}] not supported");
throw new Swoole\Curl\Exception("swoole_curl_setopt(): option[{$opt}] is not supported");
}
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion library/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function swoole_array(array $array = []): Swoole\ArrayObject
* @param $default_value
* @return mixed
*/
function swoole_array_default_value(array $array, $key, $default_value = '')
function swoole_array_default_value(array $array, $key, $default_value = null)
{
return array_key_exists($key, $array) ? $array[$key] : $default_value;
}
78 changes: 63 additions & 15 deletions php_swoole_library.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static const char* swoole_library_source_core_http_status_code =

static const char* swoole_library_source_core_curl_handler =
"\n"
"/** @noinspection PhpDuplicateSwitchCaseBodyInspection */\n"
"\n"
"namespace Swoole\\Curl;\n"
"\n"
Expand All @@ -208,7 +209,7 @@ static const char* swoole_library_source_core_curl_handler =
"class Handler\n"
"{\n"
" private const ERRORS = [\n"
" CURLE_URL_MALFORMAT => 'No URL set!',\n"
" CURLE_URL_MALFORMAT => 'Missing URL',\n"
" ];\n"
"\n"
" /**\n"
Expand Down Expand Up @@ -252,6 +253,8 @@ static const char* swoole_library_source_core_curl_handler =
" private $withFileTime = false;\n"
" private $urlInfo;\n"
" private $postData;\n"
" private $infile;\n"
" private $infileSize = PHP_INT_MAX;\n"
" private $outputStream;\n"
" private $proxy;\n"
" private $clientOptions = [];\n"
Expand Down Expand Up @@ -293,8 +296,12 @@ static const char* swoole_library_source_core_curl_handler =
" }\n"
" $this->info['url'] = $url;\n"
" $info = parse_url($url);\n"
" if (!is_array($info)) {\n"
" $this->setError(CURLE_URL_MALFORMAT, \"URL[{$url}] using bad/illegal format or missing URL\");;\n"
" return;\n"
" }\n"
" $proto = swoole_array_default_value($info, 'scheme');\n"
" if ($proto != 'http' and $proto != 'https') {\n"
" if ($proto !== 'http' and $proto !== 'https') {\n"
" $this->setError(CURLE_UNSUPPORTED_PROTOCOL, \"Protocol \\\"{$proto}\\\" not supported or disabled in libcurl\");\n"
" return;\n"
" }\n"
Expand All @@ -317,7 +324,7 @@ static const char* swoole_library_source_core_curl_handler =
" * Socket\n"
" */\n"
" $client = $this->client;\n"
" if (!$client) {\n"
" if (!$client || !$this->urlInfo) {\n"
" if (!$this->errCode) {\n"
" $this->setError(CURLE_URL_MALFORMAT);\n"
" }\n"
Expand Down Expand Up @@ -363,6 +370,25 @@ static const char* swoole_library_source_core_curl_handler =
" }\n"
" $client->setMethod($this->method);\n"
" /**\n"
" * Infile\n"
" */\n"
" if ($this->infile) {\n"
" $data = '';\n"
" while (true) {\n"
" $nLength = $this->infileSize - strlen($data);\n"
" if ($nLength === 0) {\n"
" break;\n"
" }\n"
" if (feof($this->infile)) {\n"
" break;\n"
" }\n"
" $data .= fread($this->infile, $nLength);\n"
" }\n"
" $client->setData($data);\n"
" $this->infile = null;\n"
" $this->infileSize = PHP_INT_MAX;\n"
" }\n"
" /**\n"
" * Upload File\n"
" */\n"
" if ($this->postData and is_array($this->postData)) {\n"
Expand Down Expand Up @@ -537,6 +563,18 @@ static const char* swoole_library_source_core_curl_handler =
" public function setOption(int $opt, $value): bool\n"
" {\n"
" switch ($opt) {\n"
" // case CURLOPT_STDERR:\n"
" // case CURLOPT_WRITEHEADER:\n"
" case CURLOPT_FILE:\n"
" case CURLOPT_INFILE:\n"
" if (!is_resource($value)) {\n"
" trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): supplied argument is not a valid File-Handle resource');\n"
" return false;\n"
" }\n"
" break;\n"
" }\n"
"\n"
" switch ($opt) {\n"
" /**\n"
" * Basic\n"
" */\n"
Expand All @@ -563,18 +601,18 @@ static const char* swoole_library_source_core_curl_handler =
" /**\n"
" * Ignore options\n"
" */\n"
" case CURLOPT_VERBOSE:\n"
" // trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): CURLOPT_VERBOSE is not supported');\n"
" case CURLOPT_SSLVERSION:\n"
" case CURLOPT_NOSIGNAL:\n"
" case CURLOPT_FRESH_CONNECT:\n"
" /**\n"
" * From PHP 5.1.3, this option has no effect: the raw output will always be returned when CURLOPT_RETURNTRANSFER is used.\n"
" */\n"
" case CURLOPT_BINARYTRANSFER:\n"
" /**\n"
" * TODO\n"
" */\n"
" case CURLOPT_VERBOSE:\n"
" /**\n"
" * From PHP 5.1.3, this option has no effect: the raw output will always be returned when CURLOPT_RETURNTRANSFER is used.\n"
" */\n"
" case CURLOPT_BINARYTRANSFER: /* TODO */\n"
" case CURLOPT_DNS_CACHE_TIMEOUT:\n"
" case CURLOPT_STDERR:\n"
" case CURLOPT_WRITEHEADER:\n"
" break;\n"
" /**\n"
" * SSL\n"
Expand All @@ -599,7 +637,7 @@ static const char* swoole_library_source_core_curl_handler =
" */\n"
" case CURLOPT_SAFE_UPLOAD:\n"
" if (!$value) {\n"
" trigger_error('curl_setopt(): Disabling safe uploads is no longer supported', E_USER_WARNING);\n"
" trigger_error('swoole_curl_setopt(): Disabling safe uploads is no longer supported', E_USER_WARNING);\n"
" }\n"
" break;\n"
" /**\n"
Expand Down Expand Up @@ -635,15 +673,16 @@ static const char* swoole_library_source_core_curl_handler =
" break;\n"
"\n"
" case CURLOPT_CUSTOMREQUEST:\n"
" $this->method = (string)$value;\n"
" break;\n"
" case CURLOPT_PROTOCOLS:\n"
" if ($value > 3) {\n"
" throw new Swoole\\Curl\\Exception(\"option[{$opt}={$value}] not supported\");\n"
" throw new Swoole\\Curl\\Exception(\"swoole_curl_setopt(): CURLOPT_PROTOCOLS[{$value}] is not supported\");\n"
" }\n"
" break;\n"
" case CURLOPT_HTTP_VERSION:\n"
" if ($value != CURL_HTTP_VERSION_1_1) {\n"
" trigger_error(\"swoole_curl: http version[{$value}] not supported\", E_USER_WARNING);\n"
" trigger_error(\"swoole_curl_setopt(): CURLOPT_HTTP_VERSION[{$value}] is not supported\", E_USER_WARNING);\n"
" }\n"
" break;\n"
" /**\n"
Expand Down Expand Up @@ -694,8 +733,17 @@ static const char* swoole_library_source_core_curl_handler =
" case CURLOPT_MAXREDIRS:\n"
" $this->maxRedirs = $value;\n"
" break;\n"
" case CURLOPT_PUT:\n"
" $this->method = 'PUT';\n"
" break;\n"
" case CURLOPT_INFILE:\n"
" $this->infile = $value;\n"
" break;\n"
" case CURLOPT_INFILESIZE:\n"
" $this->infileSize = $value;\n"
" break;\n"
" default:\n"
" throw new Swoole\\Curl\\Exception(\"option[{$opt}] not supported\");\n"
" throw new Swoole\\Curl\\Exception(\"swoole_curl_setopt(): option[{$opt}] is not supported\");\n"
" }\n"
" return true;\n"
" }\n"
Expand Down
7 changes: 4 additions & 3 deletions tests/include/lib/src/CurlManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Swoole\Process;
use Swoole;
use function Swoole\Coroutine\run as run;

class CurlManager
{
Expand All @@ -18,7 +19,7 @@ protected function runCliServer($port)
{
$proc = new Process(function (Process $p) use ($port) {
$exec = "/usr/bin/env php -t " . __DIR__ . " -n -S 127.0.0.1:{$port} " . __DIR__ . "/responder/get.php";
$p->exec('/bin/sh', array('-c', $exec));
$p->exec('/bin/sh', ['-c', $exec]);
}, true, 1);

$proc->start();
Expand All @@ -45,13 +46,13 @@ function run(callable $fn, $createCliServer = true)
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_CURL);
}

go(function () use ($fn, $proc) {
run(function () use ($fn, $proc) {
$fn("127.0.0.1:{$this->port}");
if ($proc) {
Swoole\Process::kill($proc->pid);
}
});
Swoole\Event::wait();

if ($createCliServer) {
Process::wait();
}
Expand Down
2 changes: 1 addition & 1 deletion tests/swoole_library/curl/basic/12.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ $cm->run(function ($host) {
--EXPECTF--
*** Testing curl with HTTP/1.0 ***

Warning: swoole_curl: http version[1] not supported in %s on line %d
Warning: swoole_curl_setopt(): CURLOPT_HTTP_VERSION[%d] is not supported in %s on line %d
string(8) "HTTP/1.1"
===DONE===
Loading