diff --git a/CMakeLists.txt b/CMakeLists.txt
index 963cf247ed3..d75dcdc0e64 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
PROJECT(libswoole)
ENABLE_LANGUAGE(ASM)
-SET(SWOOLE_VERSION 4.5.10)
+SET(SWOOLE_VERSION 4.5.11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -g")
diff --git a/ext-src/php_swoole_library.h b/ext-src/php_swoole_library.h
index 408c4841f48..857b453aa3a 100644
--- a/ext-src/php_swoole_library.h
+++ b/ext-src/php_swoole_library.h
@@ -2,7 +2,7 @@
* Generated by build-library.php, Please DO NOT modify!
*/
-/* $Id: 715c851e14c6db497c509fc781153df5e00e96c0 */
+/* $Id: 40b2539ebfe9e9cd9c20234d1df2649d87b4bfa2 */
static const char* swoole_library_source_constants =
"\n"
@@ -3690,7 +3690,7 @@ static const char* swoole_library_source_core_curl_handler =
" 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"
+ " trigger_error('swoole_curl_setopt(): supplied argument is not a valid File-Handle resource', E_USER_WARNING);\n"
" return false;\n"
" }\n"
" break;\n"
@@ -3776,7 +3776,7 @@ static const char* swoole_library_source_core_curl_handler =
" * Ignore options\n"
" */\n"
" case CURLOPT_VERBOSE:\n"
- " // trigger_error(E_USER_WARNING, 'swoole_curl_setopt(): CURLOPT_VERBOSE is not supported');\n"
+ " // trigger_error('swoole_curl_setopt(): CURLOPT_VERBOSE is not supported', E_USER_WARNING);\n"
" case CURLOPT_SSLVERSION:\n"
" case CURLOPT_NOSIGNAL:\n"
" case CURLOPT_FRESH_CONNECT:\n"
@@ -3995,9 +3995,20 @@ static const char* swoole_library_source_core_curl_handler =
" * Http Proxy\n"
" */\n"
" if ($this->proxy) {\n"
- " $proxy = explode(':', $this->proxy);\n"
- " $proxyPort = $proxy[1] ?? $this->proxyPort;\n"
- " $proxy = $proxy[0];\n"
+ " $parse = parse_url($this->proxy);\n"
+ " $proxy = $parse['host'] ?? $parse['path'];\n"
+ " $proxyPort = $parse['port'] ?? $this->proxyPort;\n"
+ " $proxyUsername = $parse['user'] ?? $this->proxyUsername;\n"
+ " $proxyPassword = $parse['pass'] ?? $this->proxyPassword;\n"
+ " $proxyType = $parse['scheme'] ?? $this->proxyType;\n"
+ " if (is_string($proxyType)) {\n"
+ " if ($proxyType === 'socks5') {\n"
+ " $proxyType = CURLPROXY_SOCKS5;\n"
+ " } else {\n"
+ " $proxyType = CURLPROXY_HTTP;\n"
+ " }\n"
+ " }\n"
+ "\n"
" if (!filter_var($proxy, FILTER_VALIDATE_IP)) {\n"
" $ip = Swoole\\Coroutine::gethostbyname($proxy, AF_INET, $this->clientOptions['connect_timeout'] ?? -1);\n"
" if (!$ip) {\n"
@@ -4006,25 +4017,25 @@ static const char* swoole_library_source_core_curl_handler =
" }\n"
" $this->proxy = $proxy = $ip;\n"
" }\n"
- " switch ($this->proxyType) {\n"
+ " switch ($proxyType) {\n"
" case CURLPROXY_HTTP:\n"
" $proxyOptions = [\n"
" 'http_proxy_host' => $proxy,\n"
" 'http_proxy_port' => $proxyPort,\n"
- " 'http_proxy_username' => $this->proxyUsername,\n"
- " 'http_proxy_password' => $this->proxyPassword,\n"
+ " 'http_proxy_username' => $proxyUsername,\n"
+ " 'http_proxy_password' => $proxyPassword,\n"
" ];\n"
" break;\n"
" case CURLPROXY_SOCKS5:\n"
" $proxyOptions = [\n"
" 'socks5_host' => $proxy,\n"
" 'socks5_port' => $proxyPort,\n"
- " 'socks5_username' => $this->proxyUsername,\n"
- " 'socks5_password' => $this->proxyPassword,\n"
+ " 'socks5_username' => $proxyUsername,\n"
+ " 'socks5_password' => $proxyPassword,\n"
" ];\n"
" break;\n"
" default:\n"
- " throw new CurlException(\"Unexpected proxy type [{$this->proxyType}]\");\n"
+ " throw new CurlException(\"Unexpected proxy type [{$proxyType}]\");\n"
" }\n"
" }\n"
" /*\n"
@@ -4261,9 +4272,11 @@ static const char* swoole_library_source_core_curl_handler =
" }\n"
" $redirectUri['path'] = $path . $location;\n"
" }\n"
- " foreach ($uri as $k => $v) {\n"
- " if (!in_array($k, ['path', 'query'])) {\n"
- " $redirectUri[$k] = $v;\n"
+ " if (is_array($uri)) {\n"
+ " foreach ($uri as $k => $v) {\n"
+ " if (!in_array($k, ['path', 'query'])) {\n"
+ " $redirectUri[$k] = $v;\n"
+ " }\n"
" }\n"
" }\n"
" }\n"
diff --git a/ext-src/swoole_runtime.cc b/ext-src/swoole_runtime.cc
index 0a4fb06bf6a..66686b5d381 100644
--- a/ext-src/swoole_runtime.cc
+++ b/ext-src/swoole_runtime.cc
@@ -95,8 +95,7 @@ ZEND_END_ARG_INFO()
static zend_class_entry *swoole_runtime_ce;
-static php_stream_ops socket_ops
-{
+static php_stream_ops socket_ops {
socket_write,
socket_read,
socket_close,
@@ -108,20 +107,16 @@ static php_stream_ops socket_ops
socket_set_option,
};
-struct php_swoole_netstream_data_t
-{
+struct php_swoole_netstream_data_t {
php_netstream_data_t stream;
Socket *socket;
bool blocking;
- double read_timeout;
- double write_timeout;
};
static bool hook_init = false;
static int hook_flags = 0;
-static struct
-{
+static struct {
php_stream_transport_factory tcp;
php_stream_transport_factory udp;
php_stream_transport_factory _unix;
@@ -256,8 +251,7 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po
return host;
}
-static php_stream_size_t socket_write(php_stream *stream, const char *buf, size_t count)
-{
+static php_stream_size_t socket_write(php_stream *stream, const char *buf, size_t count) {
php_swoole_netstream_data_t *abstract;
Socket *sock;
ssize_t didwrite = -1;
@@ -272,7 +266,12 @@ static php_stream_size_t socket_write(php_stream *stream, const char *buf, size_
goto _exit;
}
- didwrite = sock->send_all(buf, count);
+ if (abstract->blocking) {
+ didwrite = sock->send_all(buf, count);
+ } else {
+ didwrite = sock->get_socket()->send(buf, count, 0);
+ sock->set_err(errno);
+ }
if (didwrite < 0 || (size_t) didwrite != count) {
/* we do not expect the outer layer to continue to call the send syscall in a loop
@@ -289,6 +288,16 @@ static php_stream_size_t socket_write(php_stream *stream, const char *buf, size_
php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), didwrite, 0);
}
+ if (didwrite < 0) {
+ if (sock->errCode == ETIMEDOUT || sock->get_socket()->catch_error(sock->errCode) == SW_WAIT) {
+ didwrite = 0;
+ } else {
+ stream->eof = 1;
+ }
+ } else if (didwrite == 0) {
+ stream->eof = 1;
+ }
+
_exit:
#if PHP_VERSION_ID < 70400
if (didwrite < 0) {
@@ -314,17 +323,27 @@ static php_stream_size_t socket_read(php_stream *stream, char *buf, size_t count
goto _exit;
}
- nr_bytes = sock->recv(buf, count);
+ if (abstract->blocking) {
+ nr_bytes = sock->recv(buf, count);
+ } else {
+ nr_bytes = sock->get_socket()->recv(buf, count, 0);
+ sock->set_err(errno);
+ }
- /**
- * sock->errCode != ETIMEDOUT : Compatible with sync blocking IO
- */
- stream->eof = (nr_bytes == 0 || (nr_bytes == -1 && sock->errCode != ETIMEDOUT &&
- sock->get_socket()->catch_error(sock->errCode) == SW_CLOSE));
if (nr_bytes > 0) {
php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0);
}
+ if (nr_bytes < 0) {
+ if (sock->errCode == ETIMEDOUT || sock->get_socket()->catch_error(sock->errCode) == SW_WAIT) {
+ nr_bytes = 0;
+ } else {
+ stream->eof = 1;
+ }
+ } else if (nr_bytes == 0) {
+ stream->eof = 1;
+ }
+
_exit:
#if PHP_VERSION_ID < 70400
if (nr_bytes < 0) {
@@ -765,14 +784,6 @@ static int socket_set_option(php_stream *stream, int option, int value, void *pt
break;
}
abstract->blocking = (bool) value;
- if (abstract->blocking) {
- sock->set_timeout(abstract->read_timeout, Socket::TIMEOUT_READ);
- sock->set_timeout(abstract->write_timeout, Socket::TIMEOUT_WRITE);
- } else {
- abstract->read_timeout = sock->get_timeout(Socket::TIMEOUT_READ);
- abstract->write_timeout = sock->get_timeout(Socket::TIMEOUT_WRITE);
- sock->set_timeout(0.001, Socket::TIMEOUT_READ | Socket::TIMEOUT_WRITE);
- }
break;
case PHP_STREAM_OPTION_XPORT_API: {
return socket_xport_api(stream, sock, (php_stream_xport_param *) ptrparam STREAMS_CC);
diff --git a/include/swoole_socket.h b/include/swoole_socket.h
index e22fdbfca03..cfd5371891f 100644
--- a/include/swoole_socket.h
+++ b/include/swoole_socket.h
@@ -445,7 +445,7 @@ struct Socket {
ssize_t sendto_blocking(const Address &dst_addr, const void *__buf, size_t __n, int flags = 0);
ssize_t recvfrom_blocking(char *__buf, size_t __len, int flags, Address *sa);
- inline ssize_t sendto(const char *dst_host, int dst_port, const void *data, size_t len, int flags = 0) {
+ inline ssize_t sendto(const char *dst_host, int dst_port, const void *data, size_t len, int flags = 0) const {
Address addr = {};
if (!addr.assign(socket_type, dst_host, dst_port)) {
return SW_ERR;
@@ -453,20 +453,18 @@ struct Socket {
return sendto(addr, data, len, flags);
}
- inline ssize_t sendto(const Address &dst_addr, const void *data, size_t len, int flags) {
+ inline ssize_t sendto(const Address &dst_addr, const void *data, size_t len, int flags) const {
return ::sendto(fd, data, len, flags, &dst_addr.addr.ss, dst_addr.len);
}
- inline int catch_error(int err) {
+ inline int catch_error(int err) const {
switch (err) {
case EFAULT:
abort();
return SW_ERROR;
case EBADF:
case ECONNRESET:
-#ifdef __CYGWIN__
case ECONNABORTED:
-#endif
case EPIPE:
case ENOTCONN:
case ETIMEDOUT:
@@ -479,6 +477,9 @@ struct Socket {
case SW_ERROR_SSL_RESET:
return SW_CLOSE;
case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK:
+#endif
#ifdef HAVE_KQUEUE
case ENOBUFS:
#endif
diff --git a/include/swoole_version.h b/include/swoole_version.h
index 38b512995af..ae9b1b892ab 100644
--- a/include/swoole_version.h
+++ b/include/swoole_version.h
@@ -20,10 +20,10 @@
#define SWOOLE_MAJOR_VERSION 4
#define SWOOLE_MINOR_VERSION 5
-#define SWOOLE_RELEASE_VERSION 10
+#define SWOOLE_RELEASE_VERSION 11
#define SWOOLE_EXTRA_VERSION ""
-#define SWOOLE_VERSION "4.5.10"
-#define SWOOLE_VERSION_ID 40510
+#define SWOOLE_VERSION "4.5.11"
+#define SWOOLE_VERSION_ID 40511
#define SWOOLE_API_VERSION_ID 0x202011a
#define SWOOLE_BUG_REPORT \
diff --git a/package.xml b/package.xml
index e28f4f0ff78..bacae683491 100644
--- a/package.xml
+++ b/package.xml
@@ -42,10 +42,10 @@
shenzhe163@gmail.com
yes
- 2020-12-22
-
+ 2021-01-08
+
- 4.5.10
+ 4.5.11
4.0
@@ -54,11 +54,19 @@
Apache2.0
+ Enhancement
+ ---
+ * Optimize table (#3959) (@matyhtf)
+ * Enhancement CURLOPT_PROXY (swoole/library#87) (@sy-records)
+
Fixed
---
- * Fixed #3906, sync master (93901dc0) (@matyhtf)
- * Fixed PHP8 compatibility (f0dc6d32) (@matyhtf)
- * Fixed connection_list error (#3948) (@sy-records)
+ * Clear all columns when incr and decr (#3956) (@matyhtf)
+ * Fixed compile error (49fea171) (@matyhtf)
+ * Fixed fread bugs (#3972) (@matyhtf)
+ * Fixed openssl thread safety issue (7ee2c1a0) (@matyhtf)
+ * Fixed Invalid argument supplied for foreach (swoole/library#80) (@sy-records)
+ * Fix trigger_error param error (swoole/library#86) (@sy-records)
@@ -1450,6 +1458,7 @@
+
@@ -1727,6 +1736,7 @@
+
diff --git a/src/server/master.cc b/src/server/master.cc
index 32b3975a0e1..7fe66619ca8 100644
--- a/src/server/master.cc
+++ b/src/server/master.cc
@@ -343,7 +343,7 @@ int Server::start_check() {
/**
* OpenSSL thread-safe
*/
- if (is_base_mode()) {
+ if (is_process_mode() && !single_thread) {
swSSL_init_thread_safety();
}
#endif
diff --git a/tests/include/lib/src/ProcessManager.php b/tests/include/lib/src/ProcessManager.php
index 72c7bac719b..6655b89aa83 100644
--- a/tests/include/lib/src/ProcessManager.php
+++ b/tests/include/lib/src/ProcessManager.php
@@ -50,6 +50,7 @@ class ProcessManager
protected $childStatus = 255;
protected $expectExitSignal = [0, SIGTERM];
protected $parentFirst = false;
+ protected $killed = false;
/**
* @var Process
*/
@@ -238,7 +239,8 @@ public function kill(bool $force = false)
if (!defined('PCNTL_ESRCH')) {
define('PCNTL_ESRCH', 3);
}
- if (!$this->alone && $this->childPid) {
+ if (!$this->alone and !$this->killed and $this->childPid) {
+ $this->killed = true;
if ($force || (!@Process::kill($this->childPid) && swoole_errno() !== PCNTL_ESRCH)) {
if (!@Process::kill($this->childPid, SIGKILL) && swoole_errno() !== PCNTL_ESRCH) {
exit('KILL CHILD PROCESS ERROR');
diff --git a/tests/swoole_http_client_coro/websocket/bug_01.phpt b/tests/swoole_http_client_coro/websocket/bug_01.phpt
index eca56c80013..4eebef0b56c 100644
--- a/tests/swoole_http_client_coro/websocket/bug_01.phpt
+++ b/tests/swoole_http_client_coro/websocket/bug_01.phpt
@@ -4,7 +4,7 @@ swoole_http_client_coro/websocket: handshake + frame
--FILE--
+--FILE--
+
+--EXPECT--
diff --git a/tests/swoole_runtime/stream_get_meta_data.phpt b/tests/swoole_runtime/stream_get_meta_data.phpt
index 8b7bfa6ba3d..7690f6934d1 100644
--- a/tests/swoole_runtime/stream_get_meta_data.phpt
+++ b/tests/swoole_runtime/stream_get_meta_data.phpt
@@ -6,6 +6,9 @@ swoole_runtime: stream_get_meta_data
parentFunc = function ($pid) use ($pm)
-{
+$pm->parentFunc = function ($pid) use ($pm) {
$port = $pm->getFreePort();
test($port);
- swoole_runtime::enableCoroutine();
- go(function() use($port) {
+ Runtime::setHookFlags(SWOOLE_HOOK_ALL);
+ Co\run(function () use ($port) {
test($port);
});
- swoole_event_wait();
$pm->kill();
};
-$pm->childFunc = function () use ($pm)
-{
- $serv = new \swoole_server(TCP_SERVER_HOST, $pm->getFreePort(), SWOOLE_BASE);
- $socket = $serv->getSocket();
+$pm->childFunc = function () use ($pm) {
+ $serv = new Server(TCP_SERVER_HOST, $pm->getFreePort(), SWOOLE_BASE);
$serv->set([
"worker_num" => 1,
'log_file' => '/dev/null',
]);
- $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm)
- {
+ $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) {
$pm->wakeup();
});
- $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) use ($socket)
- {
+ $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) {
//donot send any
});
$serv->start();