fix:更新已知bug,优化代码
This commit is contained in:
@@ -16,6 +16,7 @@ namespace Workerman\Connection;
|
||||
/**
|
||||
* ConnectionInterface.
|
||||
*/
|
||||
#[\AllowDynamicProperties]
|
||||
abstract class ConnectionInterface
|
||||
{
|
||||
/**
|
||||
|
||||
26
vendor/workerman/workerman/Events/Select.php
vendored
26
vendor/workerman/workerman/Events/Select.php
vendored
@@ -13,6 +13,9 @@
|
||||
*/
|
||||
namespace Workerman\Events;
|
||||
|
||||
use Throwable;
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* select eventloop
|
||||
*/
|
||||
@@ -211,6 +214,7 @@ class Select implements EventInterface
|
||||
*/
|
||||
protected function tick()
|
||||
{
|
||||
$tasks_to_insert = [];
|
||||
while (!$this->_scheduler->isEmpty()) {
|
||||
$scheduler_data = $this->_scheduler->top();
|
||||
$timer_id = $scheduler_data['data'];
|
||||
@@ -228,14 +232,28 @@ class Select implements EventInterface
|
||||
$task_data = $this->_eventTimer[$timer_id];
|
||||
if ($task_data[2] === self::EV_TIMER) {
|
||||
$next_run_time = $time_now + $task_data[3];
|
||||
$this->_scheduler->insert($timer_id, -$next_run_time);
|
||||
$tasks_to_insert[] = [$timer_id, -$next_run_time];
|
||||
}
|
||||
try {
|
||||
\call_user_func_array($task_data[0], $task_data[1]);
|
||||
} catch (Throwable $e) {
|
||||
Worker::stopAll(250, $e);
|
||||
}
|
||||
\call_user_func_array($task_data[0], $task_data[1]);
|
||||
if (isset($this->_eventTimer[$timer_id]) && $task_data[2] === self::EV_TIMER_ONCE) {
|
||||
$this->del($timer_id, self::EV_TIMER_ONCE);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach ($tasks_to_insert as $item) {
|
||||
$this->_scheduler->insert($item[0], $item[1]);
|
||||
}
|
||||
if (!$this->_scheduler->isEmpty()) {
|
||||
$scheduler_data = $this->_scheduler->top();
|
||||
$next_run_time = -$scheduler_data['priority'];
|
||||
$time_now = \microtime(true);
|
||||
$this->_selectTimeout = \max((int) (($next_run_time - $time_now) * 1000000), 0);
|
||||
return;
|
||||
}
|
||||
$this->_selectTimeout = 100000000;
|
||||
@@ -275,10 +293,8 @@ class Select implements EventInterface
|
||||
|
||||
} else {
|
||||
$this->_selectTimeout >= 1 && usleep($this->_selectTimeout);
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
|
||||
if (!$this->_scheduler->isEmpty()) {
|
||||
$this->tick();
|
||||
}
|
||||
|
||||
@@ -1,584 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of workerman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author 爬山虎<blogdaren@163.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Protocols\FastCGI;
|
||||
|
||||
use Workerman\Worker;
|
||||
use Workerman\Protocols\Fcgi;
|
||||
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* allowed request methods
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const ALLOWED_REQUEST_METHODS = ['GET', 'POST', 'PUT', 'HEAD', 'DELETE'];
|
||||
|
||||
/**
|
||||
* allowed FastCGI roles
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const ALLOWED_ROLES = [
|
||||
Fcgi::FCGI_RESPONDER,
|
||||
Fcgi::FCGI_AUTHORIZER,
|
||||
Fcgi::FCGI_FILTER,
|
||||
];
|
||||
|
||||
/**
|
||||
* allowed content type
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
const ALLOWED_CONTENT_TYPES = [
|
||||
self::MIME_URL_ENCODED_FORM_DATA,
|
||||
self::MIME_MULTI_PART_FORM_DATA,
|
||||
self::MIME_JSON_DATA,
|
||||
];
|
||||
|
||||
/**
|
||||
* the MIME type of url encoded form data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MIME_URL_ENCODED_FORM_DATA = 'application/x-www-form-urlencoded';
|
||||
|
||||
/**
|
||||
* the MIME type of multi part form data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MIME_MULTI_PART_FORM_DATA = 'multipart/form-data; boundary=__X_FASTCGI_CLIENT_BOUNDARY__';
|
||||
|
||||
/**
|
||||
* the MIME type of json data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MIME_JSON_DATA = 'application/json';
|
||||
|
||||
/**
|
||||
* FastCGI script to be executed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $script = '';
|
||||
|
||||
/**
|
||||
* content MIME Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $contentType = self::MIME_URL_ENCODED_FORM_DATA;
|
||||
|
||||
/**
|
||||
* content data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* content length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $contentLength = 0;
|
||||
|
||||
/**
|
||||
* request uri
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $requestUri = '';
|
||||
|
||||
/**
|
||||
* request method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $requestMethod = 'GET';
|
||||
|
||||
/**
|
||||
* query string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $queryString = '';
|
||||
|
||||
/**
|
||||
* gateway inteface
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $gatewayInterface = 'FastCGI/1.0';
|
||||
|
||||
/**
|
||||
* server software
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $serverSoftware = 'FastCGI-Client';
|
||||
|
||||
/**
|
||||
* server name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $serverName = 'localhost';
|
||||
|
||||
/**
|
||||
* request id
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $requestId = 0;
|
||||
|
||||
/**
|
||||
* proxy counter for request id
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
static protected $_idCounter = 1;
|
||||
|
||||
/**
|
||||
* custom params
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $customParams = [];
|
||||
|
||||
/**
|
||||
* indicates FastCGI server to keep connection alive or not after finishing one request
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $keepAlive = true;
|
||||
|
||||
/**
|
||||
* indicates FastCGI server to play the specific role
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $role = Fcgi::FCGI_RESPONDER;
|
||||
|
||||
/**
|
||||
* @brief __construct
|
||||
*
|
||||
* @param string $script
|
||||
* @param string|array $content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($script = '', $content = '')
|
||||
{
|
||||
$this->setScript($script);
|
||||
$this->setContent($content);
|
||||
(self::$_idCounter >= (1 << 16)) && self::$_idCounter = 0;
|
||||
$this->requestId = self::$_idCounter++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get request id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRequestId()
|
||||
{
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the role
|
||||
*
|
||||
* @param int $role
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setRole($role = Fcgi::FCGI_RESPONDER)
|
||||
{
|
||||
if(!is_int($role) || !in_array($role, static::ALLOWED_ROLES))
|
||||
{
|
||||
$role = Fcgi::FCGI_RESPONDER;
|
||||
}
|
||||
|
||||
$this->role = $role;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the role
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set connection alive status
|
||||
*
|
||||
* @param boolean $status
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setKeepAlive($status = true)
|
||||
{
|
||||
$this->keepAlive = !is_bool($status) ? true : $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get connection alive status
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getKeepAlive()
|
||||
{
|
||||
return $this->keepAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get server software
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServerSoftware()
|
||||
{
|
||||
return $this->serverSoftware;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set server software
|
||||
*
|
||||
* @param string $software
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setServerSoftware($software)
|
||||
{
|
||||
if(!empty($software) && \is_string($software))
|
||||
{
|
||||
$this->serverSoftware = $software;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get server name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServerName()
|
||||
{
|
||||
return $this->serverName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set server name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setServerName($name)
|
||||
{
|
||||
if(!empty($name) && \is_string($name))
|
||||
{
|
||||
$this->serverName = $name;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get content type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set content type
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setContentType($type)
|
||||
{
|
||||
if(!\is_string($type) || !in_array($type, static::ALLOWED_CONTENT_TYPES))
|
||||
{
|
||||
$type = static::MIME_URL_ENCODED_FORM_DATA;
|
||||
}
|
||||
|
||||
$this->contentType = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set content
|
||||
*
|
||||
* @param string|array $content
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
if(\is_string($content) || \is_array($content))
|
||||
{
|
||||
$this->content = !\is_string($content) ? http_build_query($content) : $content;
|
||||
$this->contentLength = \strlen($this->content);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get content length
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getContentLength()
|
||||
{
|
||||
return $this->contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get gateway interface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGatewayInterface()
|
||||
{
|
||||
return $this->gatewayInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set FastCGI script
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setScript($filename)
|
||||
{
|
||||
if(!empty($filename) && \is_string($filename))
|
||||
{
|
||||
$this->script = $filename;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get FastCGI script
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScript()
|
||||
{
|
||||
return $this->script;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set custom params
|
||||
*
|
||||
* @param array $pair
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setCustomParams($pair)
|
||||
{
|
||||
if(!\is_array($pair)) return $this;
|
||||
|
||||
foreach($pair as $k => $v)
|
||||
{
|
||||
if(!\is_string($v)) continue;
|
||||
$this->customParams[$k] = $v;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief append custom params
|
||||
*
|
||||
* @param array $pair
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function appendCustomParams($pair)
|
||||
{
|
||||
if(\is_array($pair))
|
||||
{
|
||||
$this->customParams = \array_merge($this->customParams, $pair);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reset custom params
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function resetCustomParams()
|
||||
{
|
||||
$this->customParams = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set query string
|
||||
*
|
||||
* @param string|array $string
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setQueryString($data = '')
|
||||
{
|
||||
if(\is_string($data) || \is_array($data))
|
||||
{
|
||||
$this->queryString = !\is_string($data) ? http_build_query($data) : $data;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get query string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryString()
|
||||
{
|
||||
return $this->queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get custom params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomParams()
|
||||
{
|
||||
return $this->customParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get all params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return \array_merge($this->customParams, $this->getDefaultParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get default params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultParams()
|
||||
{
|
||||
return [
|
||||
'GATEWAY_INTERFACE' => $this->getGatewayInterface(),
|
||||
'SCRIPT_FILENAME' => $this->getScript(),
|
||||
'REQUEST_METHOD' => $this->getRequestMethod(),
|
||||
'REQUEST_URI' => $this->getRequestUri(),
|
||||
'QUERY_STRING' => $this->getQueryString(),
|
||||
'CONTENT_TYPE' => $this->getContentType(),
|
||||
'CONTENT_LENGTH' => $this->getContentLength(),
|
||||
'SERVER_NAME' => $this->getServerName(),
|
||||
'SERVER_SOFTWARE' => $this->getServerSoftware(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set request method
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setRequestMethod($method = 'GET')
|
||||
{
|
||||
if(!\is_string($method) || !in_array(strtoupper($method), static::ALLOWED_REQUEST_METHODS))
|
||||
{
|
||||
$method = 'GET';
|
||||
}
|
||||
|
||||
$this->requestMethod = strtoupper($method);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get request method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestMethod()
|
||||
{
|
||||
return $this->requestMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get request uri
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestUri()
|
||||
{
|
||||
return $this->requestUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set request uri
|
||||
*
|
||||
* @param string $uri
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setRequestUri($uri)
|
||||
{
|
||||
if(\is_string($uri))
|
||||
{
|
||||
$this->requestUri = $uri;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of workerman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author 爬山虎<blogdaren@163.com>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace Workerman\Protocols\FastCGI;
|
||||
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* success status
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const STATUS_OK = 200;
|
||||
|
||||
/**
|
||||
* invalid status
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const STATUS_INVALID = -1;
|
||||
|
||||
/**
|
||||
* the request id from response
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_requestId;
|
||||
|
||||
/**
|
||||
* the stdout from response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_stdout = '';
|
||||
|
||||
/**
|
||||
* the stderr from response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_stderr = '';
|
||||
|
||||
/**
|
||||
* the origin header from response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_header = '';
|
||||
|
||||
/**
|
||||
* the origin body from response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_body = '';
|
||||
|
||||
/**
|
||||
* @brief __construct
|
||||
*
|
||||
* @param int $request_id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($request_id = 0)
|
||||
{
|
||||
$this->setRequestId($request_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set request id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function setRequestId($id = 0)
|
||||
{
|
||||
$this->_requestId = (\is_int($id) && $id > 0) ? $id : -1;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set stdout
|
||||
*
|
||||
* @param string $stdout
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setStdout($stdout = '')
|
||||
{
|
||||
if(\is_string($stdout))
|
||||
{
|
||||
$this->_stdout = $stdout;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get stdout
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStdout()
|
||||
{
|
||||
return $this->_stdout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set stderr
|
||||
*
|
||||
* @param string $stderr
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function setStderr($stderr = '')
|
||||
{
|
||||
if(\is_string($stderr))
|
||||
{
|
||||
$this->_stderr = $stderr;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get stderr
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getStderr()
|
||||
{
|
||||
return $this->_stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHeader()
|
||||
{
|
||||
return $this->_header;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get request id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRequestId()
|
||||
{
|
||||
return $this->_requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief format response output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function formatOutput()
|
||||
{
|
||||
$status = static::STATUS_INVALID;
|
||||
$header = [];
|
||||
$body = '';
|
||||
$crlf_pos = \strpos($this->getStdout(), "\r\n\r\n");
|
||||
|
||||
if(false !== $crlf_pos)
|
||||
{
|
||||
$status = static::STATUS_OK;
|
||||
$head = \substr($this->getStdout(), 0, $crlf_pos);
|
||||
$body = \substr($this->getStdout(), $crlf_pos + 4);
|
||||
$this->_header = \substr($this->getStdout(), 0, $crlf_pos + 4);
|
||||
$this->_body = $body;
|
||||
$header_lines = \explode(PHP_EOL, $head);
|
||||
|
||||
foreach($header_lines as $line)
|
||||
{
|
||||
if(preg_match('/([\w-]+):\s*(.*)$/', $line, $matches))
|
||||
{
|
||||
$name = \trim($matches[1]);
|
||||
$value = \trim($matches[2]);
|
||||
|
||||
if('status' === strtolower($name))
|
||||
{
|
||||
$pos = strpos($value, ' ') ;
|
||||
$status = false !== $pos ? \substr($value, 0, $pos) : static::STATUS_OK;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!array_key_exists($name, $header))
|
||||
{
|
||||
$header[$name] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
!\is_array($header[$name]) && $header[$name] = [$header[$name]];
|
||||
$header[$name][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$output = [
|
||||
'requestId' => $this->getRequestId(),
|
||||
'status' => $status,
|
||||
'stderr' => $this->getStderr(),
|
||||
'header' => $header,
|
||||
'body' => $body,
|
||||
];
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
541
vendor/workerman/workerman/Protocols/Fcgi.php
vendored
541
vendor/workerman/workerman/Protocols/Fcgi.php
vendored
@@ -1,541 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of workerman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author 爬山虎<blogdaren@163.com>
|
||||
* @protocol http://www.mit.edu/~yandros/doc/specs/fcgi-spec.html
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Workerman\Protocols;
|
||||
|
||||
use Workerman\Worker;
|
||||
use Workerman\Connection\TcpConnection;
|
||||
use Workerman\Protocols\FastCGI\Request;
|
||||
use Workerman\Protocols\FastCGI\Response;
|
||||
|
||||
class Fcgi
|
||||
{
|
||||
/**
|
||||
* the version of fcgi protocol
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_VERSION_1 = 1;
|
||||
|
||||
/**
|
||||
* the fixed length of FCGI_Header: sizeof(FCGI_Header) === 8
|
||||
*
|
||||
* typedef struct {
|
||||
* unsigned char version;
|
||||
* unsigned char type;
|
||||
* unsigned char requestIdB1;
|
||||
* unsigned char requestIdB0;
|
||||
* unsigned char contentLengthB1;
|
||||
* unsigned char contentLengthB0;
|
||||
* unsigned char paddingLength;
|
||||
* unsigned char reserved;
|
||||
* } FCGI_Header;
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_HEADER_LEN = 8;
|
||||
|
||||
/**
|
||||
* the max length of payload
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_MAX_PAYLOAD_LEN = 65535;
|
||||
|
||||
/**
|
||||
* the reserved bit FCGI_Header
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FCGI_RESERVED = '';
|
||||
|
||||
/**
|
||||
* the padding bit FCGI_Header
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const FCGI_PADDING = '';
|
||||
|
||||
/**
|
||||
* the record type of FCGI_BEGIN_REQUEST
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_BEGIN_REQUEST = 1;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_ABORT_REQUEST
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_ABORT_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_END_REQUEST
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_END_REQUEST = 3;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_PARAMS
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_PARAMS = 4;
|
||||
|
||||
/**
|
||||
* -------------------------------------
|
||||
* the pseudo record type of FCGI_PARAMS
|
||||
* -------------------------------------
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_PARAMS_END = 4 << 3;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_STDIN
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_STDIN = 5;
|
||||
|
||||
/**
|
||||
* -------------------------------------
|
||||
* the pseudo record type of FCGI_STDIN
|
||||
* -------------------------------------
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_STDIN_END = 5 << 4;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_STDOUT
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_STDOUT = 6;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_STDERR
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_STDERR = 7;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_DATA
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_DATA = 8;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_GET_VALUES
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_GET_VALUES = 9;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_GET_VALUES_RESULT
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_GET_VALUES_RESULT = 10;
|
||||
|
||||
/**
|
||||
* the record type of FCGI_UNKNOWN_TYPE
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_UNKNOWN_TYPE = 11;
|
||||
|
||||
/**
|
||||
* the role type of FCGI_RESPONDER
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_RESPONDER = 1;
|
||||
|
||||
/**
|
||||
* the role type of FCGI_AUTHORIZER
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_AUTHORIZER = 2;
|
||||
|
||||
/**
|
||||
* the role type of FCGI_FILTER
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_FILTER = 3;
|
||||
|
||||
/**
|
||||
* the protocol status of FCGI_REQUEST_COMPLETE
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_REQUEST_COMPLETE = 0;
|
||||
|
||||
/**
|
||||
* the protocol status of FCGI_CANT_MPX_CONN
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_CANT_MPX_CONN = 1;
|
||||
|
||||
/**
|
||||
* the protocol status of FCGI_OVERLOADED
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_OVERLOADED = 2;
|
||||
|
||||
/**
|
||||
* the protocol status of FCGI_UNKNOWN_ROLE
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const FCGI_UNKNOWN_ROLE = 3;
|
||||
|
||||
/**
|
||||
* the request object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
static private $_request = NULL;
|
||||
|
||||
/**
|
||||
* check the integrity of the package
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param TcpConnection $connection
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function input($buffer, TcpConnection $connection)
|
||||
{
|
||||
$recv_len = \strlen($buffer);
|
||||
|
||||
if($recv_len < static::FCGI_HEADER_LEN) return 0;
|
||||
|
||||
if(!isset($connection->packetLength)) $connection->packetLength = 0;
|
||||
|
||||
$data = \unpack("Cversion/Ctype/nrequestId/ncontentLength/CpaddingLength/Creserved", $buffer);
|
||||
if(false === $data) return 0;
|
||||
|
||||
$chunk_len = static::FCGI_HEADER_LEN + $data['contentLength'] + $data['paddingLength'];
|
||||
if($recv_len < $chunk_len) return 0;
|
||||
|
||||
if(static::FCGI_END_REQUEST != $data['type'])
|
||||
{
|
||||
$connection->packetLength += $chunk_len;
|
||||
$next_chunk_len = static::input(\substr($buffer, $chunk_len), $connection);
|
||||
|
||||
if(0 == $next_chunk_len)
|
||||
{
|
||||
//important!! don't forget to reset to zero byte!!
|
||||
$connection->packetLength = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$connection->packetLength += $chunk_len;
|
||||
}
|
||||
|
||||
//check package length exceeds the max package length or not
|
||||
if($connection->packetLength > $connection->maxPackageSize)
|
||||
{
|
||||
$msg = "Exception: recv error package. package_length = {$connection->packetLength} ";
|
||||
$msg .= "exceeds the limit {$connection->maxPackageSize}" . PHP_EOL;
|
||||
Worker::safeEcho($msg);
|
||||
$connection->close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $connection->packetLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief decode package
|
||||
*
|
||||
* @param string $buffer
|
||||
* @param TcpConnection $connection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function decode($buffer, TcpConnection $connection)
|
||||
{
|
||||
$offset = 0;
|
||||
$stdout = $stderr = '';
|
||||
|
||||
do
|
||||
{
|
||||
$header_buffer = \substr($buffer, $offset, static::FCGI_HEADER_LEN);
|
||||
$data = \unpack("Cversion/Ctype/nrequestId/ncontentLength/CpaddingLength/Creserved", $header_buffer);
|
||||
|
||||
//we are not going to throw new \Exception("Failed to unpack header data from the binary buffer.");
|
||||
//but just break out of the loop to avoid bring much unnecessary TCP connections with TIME_WAIT status
|
||||
if(false === $data)
|
||||
{
|
||||
$stderr = "Failed to unpack header data from the binary buffer";
|
||||
Worker::safeEcho($stderr);
|
||||
$connection->close();
|
||||
break;
|
||||
}
|
||||
|
||||
$chunk_len = static::FCGI_HEADER_LEN + $data['contentLength'] + $data['paddingLength'];
|
||||
$body_buffer = \substr($buffer, $offset + static::FCGI_HEADER_LEN, $chunk_len - static::FCGI_HEADER_LEN);
|
||||
|
||||
|
||||
switch($data['type'])
|
||||
{
|
||||
case static::FCGI_STDOUT:
|
||||
$payload = \unpack("a{$data['contentLength']}contentData/a{$data['paddingLength']}paddingData", $body_buffer);
|
||||
$stdout .= $payload['contentData'];
|
||||
break;
|
||||
case static::FCGI_STDERR:
|
||||
$payload = \unpack("a{$data['contentLength']}contentData/a{$data['paddingLength']}paddingData", $body_buffer);
|
||||
$stderr .= $payload['contentData'];
|
||||
break;
|
||||
case static::FCGI_END_REQUEST:
|
||||
$payload = \unpack("NappStatus/CprotocolStatus/a3reserved", $body_buffer);
|
||||
$result = static::checkProtocolStatus($payload['protocolStatus']);
|
||||
|
||||
if(0 <> $result['code'])
|
||||
{
|
||||
$stderr = $result['msg'];
|
||||
Worker::safeEcho($stderr);
|
||||
$connection->close();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//not support yet
|
||||
$payload = '';
|
||||
break;
|
||||
}
|
||||
|
||||
$offset += $chunk_len;
|
||||
}while($offset < $connection->packetLength);
|
||||
|
||||
//important!! don't forget to reset to zero byte!!
|
||||
$connection->packetLength = 0;
|
||||
|
||||
//build response
|
||||
$response = new Response();
|
||||
$output = $response->setRequestId($data['requestId'] ?? -1)
|
||||
->setStdout($stdout)
|
||||
->setStderr($stderr)
|
||||
->formatOutput();
|
||||
|
||||
//trigger user callback as onResponse
|
||||
if(!empty($connection->onResponse) && is_callable($connection->onResponse))
|
||||
{
|
||||
try {
|
||||
\call_user_func($connection->onResponse, $connection, $response);
|
||||
} catch (\Exception $e) {
|
||||
$msg = "Exception: onResponse: " . $e->getMessage();
|
||||
Worker::safeEcho($msg);
|
||||
$connection->close();
|
||||
} catch (\Error $e) {
|
||||
$msg = "Exception: onResponse: " . $e->getMessage();
|
||||
Worker::safeEcho($msg);
|
||||
$connection->close();
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief encode package
|
||||
*
|
||||
* @param Request $request
|
||||
* @param TcpConnection $connection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(Request $request, TcpConnection $connection)
|
||||
{
|
||||
if(!$request instanceof Request) return '';
|
||||
|
||||
static::$_request = $request;
|
||||
|
||||
$packet = '';
|
||||
$packet .= static::createPacket(static::FCGI_BEGIN_REQUEST);
|
||||
$packet .= static::createPacket(static::FCGI_PARAMS);
|
||||
$packet .= static::createPacket(static::FCGI_PARAMS_END);
|
||||
$packet .= static::createPacket(static::FCGI_STDIN);
|
||||
$packet .= static::createPacket(static::FCGI_STDIN_END);
|
||||
|
||||
$connection->maxSendBufferSize = TcpConnection::$defaultMaxSendBufferSize * 10;
|
||||
$packet_len = \strlen($packet);
|
||||
|
||||
if($packet_len > $connection->maxSendBufferSize)
|
||||
{
|
||||
$msg = "Exception: send error package. package_length = {$packet_len} ";
|
||||
$msg .= "exceeds the limit {$connection->maxSendBufferSize}" . PHP_EOL;
|
||||
Worker::safeEcho($msg);
|
||||
$connection->close();
|
||||
return '';
|
||||
}
|
||||
|
||||
return $packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief pack payload
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static private function packPayload($type = '')
|
||||
{
|
||||
$payload = '';
|
||||
|
||||
switch($type)
|
||||
{
|
||||
case static::FCGI_BEGIN_REQUEST:
|
||||
$payload = \pack(
|
||||
"nCa5",
|
||||
static::$_request->getRole(),
|
||||
static::$_request->getKeepAlive(),
|
||||
static::FCGI_RESERVED
|
||||
);
|
||||
break;
|
||||
case static::FCGI_PARAMS:
|
||||
case static::FCGI_PARAMS_END:
|
||||
$payload = '';
|
||||
$params = (static::FCGI_PARAMS == $type) ? static::$_request->getParams() : [];
|
||||
foreach($params as $name => $value)
|
||||
{
|
||||
$name_len = \strlen($name);
|
||||
$value_len = \strlen($value);
|
||||
$format = [
|
||||
$name_len > 127 ? 'N' : 'C',
|
||||
$value_len > 127 ? 'N' : 'C',
|
||||
"a{$name_len}",
|
||||
"a{$value_len}",
|
||||
];
|
||||
$format = implode ('', $format);
|
||||
$payload .= \pack(
|
||||
$format,
|
||||
$name_len > 127 ? ($name_len | 0x80000000) : $name_len,
|
||||
$value_len > 127 ? ($value_len | 0x80000000) : $value_len,
|
||||
$name,
|
||||
$value
|
||||
);
|
||||
}
|
||||
break;
|
||||
case static::FCGI_STDIN:
|
||||
case static::FCGI_ABORT_REQUEST:
|
||||
case static::FCGI_DATA:
|
||||
$payload = \pack("a" . static::$_request->getContentLength(), static::$_request->getContent());
|
||||
break;
|
||||
case static::FCGI_STDIN_END:
|
||||
$payload = '';
|
||||
break;
|
||||
case static::FCGI_UNKNOWN_TYPE:
|
||||
$payload = \pack("Ca7", static::FCGI_UNKNOWN_TYPE, static::FCGI_RESERVED);
|
||||
break;
|
||||
default:
|
||||
$payload = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create request packet
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function createPacket($type = '')
|
||||
{
|
||||
$packet = '';
|
||||
$offset = 0;
|
||||
$payload = static::packPayload($type);
|
||||
$total_len = \strlen($payload);
|
||||
|
||||
//don't forget to reset pseudo record type to normal
|
||||
$type == static::FCGI_PARAMS_END && $type = static::FCGI_PARAMS;
|
||||
$type == static::FCGI_STDIN_END && $type = static::FCGI_STDIN;
|
||||
|
||||
//maybe need to split payload into many chunks
|
||||
do
|
||||
{
|
||||
$chunk = \substr($payload, $offset, static::FCGI_MAX_PAYLOAD_LEN);
|
||||
$chunk_len = \strlen($chunk);
|
||||
$remainder = \abs($chunk_len % 8);
|
||||
$padding_len = $remainder > 0 ? 8 - $remainder : 0;
|
||||
|
||||
$header = \pack(
|
||||
"CCnnCC",
|
||||
static::FCGI_VERSION_1,
|
||||
$type,
|
||||
static::$_request->getRequestId(),
|
||||
$chunk_len,
|
||||
$padding_len,
|
||||
static::FCGI_RESERVED
|
||||
);
|
||||
|
||||
$padding = \pack("a{$padding_len}", static::FCGI_PADDING);
|
||||
$packet .= $header . $chunk . $padding;
|
||||
$offset += $chunk_len;
|
||||
}while($offset < $total_len);
|
||||
|
||||
return $packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check the protocol status from FCGI_END_REQUEST body
|
||||
*
|
||||
* @param int $status
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function checkProtocolStatus($status = 0)
|
||||
{
|
||||
switch($status)
|
||||
{
|
||||
case static::FCGI_REQUEST_COMPLETE:
|
||||
$msg = 'Accepted: request completed ok';
|
||||
break;
|
||||
case static::FCGI_CANT_MPX_CONN:
|
||||
$msg = 'Rejected: FastCGI server does not support concurrent processing';
|
||||
break;
|
||||
case static::FCGI_OVERLOADED:
|
||||
$msg = 'Rejected: FastCGI server run out of resources or reached the limit';
|
||||
break;
|
||||
case static::FCGI_UNKNOWN_ROLE:
|
||||
$msg = 'Rejected: FastCGI server not support the specified role';
|
||||
break;
|
||||
default:
|
||||
$msg = 'Rejected: FastCGI server does not know what happened';
|
||||
break;
|
||||
}
|
||||
|
||||
return [
|
||||
'code' => $status,
|
||||
'msg' => $msg,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/workerman/workerman/Protocols/Http.php
vendored
49
vendor/workerman/workerman/Protocols/Http.php
vendored
@@ -94,60 +94,58 @@ class Http
|
||||
*/
|
||||
public static function input($recv_buffer, TcpConnection $connection)
|
||||
{
|
||||
static $input = array();
|
||||
static $input = [];
|
||||
if (!isset($recv_buffer[512]) && isset($input[$recv_buffer])) {
|
||||
return $input[$recv_buffer];
|
||||
}
|
||||
$crlf_pos = \strpos($recv_buffer, "\r\n\r\n");
|
||||
if (false === $crlf_pos) {
|
||||
// Judge whether the package length exceeds the limit.
|
||||
if ($recv_len = \strlen($recv_buffer) >= 16384) {
|
||||
if (\strlen($recv_buffer) >= 16384) {
|
||||
$connection->close("HTTP/1.1 413 Request Entity Too Large\r\n\r\n", true);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
$head_len = $crlf_pos + 4;
|
||||
$length = $crlf_pos + 4;
|
||||
$method = \strstr($recv_buffer, ' ', true);
|
||||
|
||||
if ($method === 'GET' || $method === 'OPTIONS' || $method === 'HEAD' || $method === 'DELETE') {
|
||||
if (!isset($recv_buffer[512])) {
|
||||
$input[$recv_buffer] = $head_len;
|
||||
if (\count($input) > 512) {
|
||||
unset($input[key($input)]);
|
||||
}
|
||||
}
|
||||
return $head_len;
|
||||
} else if ($method !== 'POST' && $method !== 'PUT' && $method !== 'PATCH') {
|
||||
if (!\in_array($method, ['GET', 'POST', 'OPTIONS', 'HEAD', 'DELETE', 'PUT', 'PATCH'])) {
|
||||
$connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$header = \substr($recv_buffer, 0, $crlf_pos);
|
||||
$length = false;
|
||||
if ($pos = \strpos($header, "\r\nContent-Length: ")) {
|
||||
$length = $head_len + (int)\substr($header, $pos + 18, 10);
|
||||
$length = $length + (int)\substr($header, $pos + 18, 10);
|
||||
$has_content_length = true;
|
||||
} else if (\preg_match("/\r\ncontent-length: ?(\d+)/i", $header, $match)) {
|
||||
$length = $head_len + $match[1];
|
||||
$length = $length + $match[1];
|
||||
$has_content_length = true;
|
||||
} else {
|
||||
$has_content_length = false;
|
||||
if (false !== stripos($header, "\r\nTransfer-Encoding:")) {
|
||||
$connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($length !== false) {
|
||||
if (!isset($recv_buffer[512])) {
|
||||
$input[$recv_buffer] = $length;
|
||||
if (\count($input) > 512) {
|
||||
unset($input[key($input)]);
|
||||
}
|
||||
}
|
||||
if ($has_content_length) {
|
||||
if ($length > $connection->maxPackageSize) {
|
||||
$connection->close("HTTP/1.1 413 Request Entity Too Large\r\n\r\n", true);
|
||||
return 0;
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
$connection->close("HTTP/1.1 400 Bad Request\r\n\r\n", true);
|
||||
return 0;
|
||||
if (!isset($recv_buffer[512])) {
|
||||
$input[$recv_buffer] = $length;
|
||||
if (\count($input) > 512) {
|
||||
unset($input[key($input)]);
|
||||
}
|
||||
}
|
||||
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,6 +219,7 @@ class Http
|
||||
$file = $response->file['file'];
|
||||
$offset = $response->file['offset'];
|
||||
$length = $response->file['length'];
|
||||
clearstatcache();
|
||||
$file_size = (int)\filesize($file);
|
||||
$body_len = $length > 0 ? $length : $file_size - $offset;
|
||||
$response->withHeaders(array(
|
||||
|
||||
@@ -520,6 +520,9 @@ class Request
|
||||
{
|
||||
$file = [];
|
||||
$boundary = "\r\n$boundary";
|
||||
if (\strlen($this->_buffer) < $section_start_offset) {
|
||||
return 0;
|
||||
}
|
||||
$section_end_offset = \strpos($this->_buffer, $boundary, $section_start_offset);
|
||||
if (!$section_end_offset) {
|
||||
return 0;
|
||||
@@ -596,7 +599,7 @@ class Request
|
||||
*/
|
||||
protected static function createSessionId()
|
||||
{
|
||||
return \bin2hex(\pack('d', \microtime(true)) . \pack('N', \mt_rand()));
|
||||
return \bin2hex(\pack('d', \microtime(true)) . random_bytes(8));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -410,7 +410,7 @@ class Session
|
||||
public function __destruct()
|
||||
{
|
||||
$this->save();
|
||||
if (\rand(1, static::$gcProbability[1]) <= static::$gcProbability[0]) {
|
||||
if (\random_int(1, static::$gcProbability[1]) <= static::$gcProbability[0]) {
|
||||
$this->gc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class FileSessionHandler implements SessionHandlerInterface
|
||||
*/
|
||||
public function write($session_id, $session_data)
|
||||
{
|
||||
$temp_file = static::$_sessionSavePath.uniqid(mt_rand(), true);
|
||||
$temp_file = static::$_sessionSavePath . uniqid(bin2hex(random_bytes(8)), true);
|
||||
if (!\file_put_contents($temp_file, $session_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
2
vendor/workerman/workerman/Protocols/Ws.php
vendored
2
vendor/workerman/workerman/Protocols/Ws.php
vendored
@@ -355,7 +355,7 @@ class Ws
|
||||
$port = $connection->getRemotePort();
|
||||
$host = $port === 80 ? $connection->getRemoteHost() : $connection->getRemoteHost() . ':' . $port;
|
||||
// Handshake header.
|
||||
$connection->websocketSecKey = \base64_encode(\md5(\mt_rand(), true));
|
||||
$connection->websocketSecKey = \base64_encode(random_bytes(16));
|
||||
$user_header = isset($connection->headers) ? $connection->headers :
|
||||
(isset($connection->wsHttpHeader) ? $connection->wsHttpHeader : null);
|
||||
$user_header_str = '';
|
||||
|
||||
48
vendor/workerman/workerman/Worker.php
vendored
48
vendor/workerman/workerman/Worker.php
vendored
@@ -26,6 +26,7 @@ use \Exception;
|
||||
* Worker class
|
||||
* A container for listening ports
|
||||
*/
|
||||
#[\AllowDynamicProperties]
|
||||
class Worker
|
||||
{
|
||||
/**
|
||||
@@ -33,7 +34,7 @@ class Worker
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '4.0.42';
|
||||
const VERSION = '4.1.4';
|
||||
|
||||
/**
|
||||
* Status starting.
|
||||
@@ -183,7 +184,7 @@ class Worker
|
||||
public $onBufferDrain = null;
|
||||
|
||||
/**
|
||||
* Emitted when worker processes stoped.
|
||||
* Emitted when worker processes stopped.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
@@ -548,11 +549,13 @@ class Worker
|
||||
{
|
||||
static::checkSapiEnv();
|
||||
static::init();
|
||||
static::lock();
|
||||
static::parseCommand();
|
||||
static::daemonize();
|
||||
static::initWorkers();
|
||||
static::installSignal();
|
||||
static::saveMasterPid();
|
||||
static::lock(\LOCK_UN);
|
||||
static::displayUI();
|
||||
static::forkWorkers();
|
||||
static::resetStd();
|
||||
@@ -629,24 +632,25 @@ class Worker
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function lock()
|
||||
protected static function lock($flag = \LOCK_EX)
|
||||
{
|
||||
$fd = \fopen(static::$_startFile, 'r');
|
||||
if ($fd && !flock($fd, LOCK_EX)) {
|
||||
static::log('Workerman['.static::$_startFile.'] already running.');
|
||||
exit;
|
||||
static $fd;
|
||||
if (\DIRECTORY_SEPARATOR !== '/') {
|
||||
return;
|
||||
}
|
||||
$lock_file = static::$pidFile . '.lock';
|
||||
$fd = $fd ?: \fopen($lock_file, 'a+');
|
||||
if ($fd) {
|
||||
flock($fd, $flag);
|
||||
if ($flag === \LOCK_UN) {
|
||||
fclose($fd);
|
||||
$fd = null;
|
||||
clearstatcache();
|
||||
if (\is_file($lock_file)) {
|
||||
unlink($lock_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function unlock()
|
||||
{
|
||||
$fd = \fopen(static::$_startFile, 'r');
|
||||
$fd && flock($fd, \LOCK_UN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1693,11 +1697,9 @@ class Worker
|
||||
// onWorkerExit
|
||||
if ($worker->onWorkerExit) {
|
||||
try {
|
||||
call_user_func($worker->onWorkerExit, $worker, $status, $pid);
|
||||
} catch (\Exception $e) {
|
||||
static::log("worker[{$worker->name}] onWorkerExit $e");
|
||||
} catch (\Error $e) {
|
||||
static::log("worker[{$worker->name}] onWorkerExit $e");
|
||||
($worker->onWorkerExit)($worker, $status, $pid);
|
||||
} catch (\Throwable $exception) {
|
||||
static::log("worker[{$worker->name}] onWorkerExit $exception");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/workerman/workerman/composer.json
vendored
2
vendor/workerman/workerman/composer.json
vendored
@@ -24,7 +24,7 @@
|
||||
"source": "https://github.com/walkor/workerman"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4"
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
|
||||
Reference in New Issue
Block a user