admin-api/vendor/yurunsoft/guzzle-swoole/src/Ring/SwooleHandler.php

228 lines
7.9 KiB
PHP

<?php
namespace Yurun\Util\Swoole\Guzzle\Ring;
use GuzzleHttp\Ring\Core;
use GuzzleHttp\Ring\Exception\RingException;
use GuzzleHttp\Ring\Future\CompletedFutureArray;
use Swoole\Coroutine;
use Yurun\Util\HttpRequest;
use Yurun\Util\YurunHttp;
use Yurun\Util\YurunHttp\Http\Psr7\Uri;
use Yurun\Util\YurunHttp\Http\Response;
class SwooleHandler
{
/**
* 选项集合.
*
* @var array
*/
protected $options;
public function __construct(array $options = [])
{
$this->options = $options;
}
/**
* @param array $request
*
* @return CompletedFutureArray
*/
public function __invoke(array $request)
{
$httpRequest = new HttpRequest();
$yurunResponse = $this->getYurunResponse($httpRequest, $request);
$response = $this->getResponse($httpRequest, $yurunResponse);
return new CompletedFutureArray($response);
}
/**
* 获取 YurunHttp Response.
*
* @param \Yurun\Util\HttpRequest $httpRequest
* @param array $request
*
* @return \Yurun\Util\YurunHttp\Http\Response
*/
protected function getYurunResponse(HttpRequest $httpRequest, array $request): Response
{
foreach ($request['client'] ?? [] as $key => $value)
{
switch ($key)
{
// Violating PSR-4 to provide more room.
case 'verify':
if ($httpRequest->isVerifyCA = $value && \is_string($value))
{
if (!file_exists($value))
{
throw new \InvalidArgumentException("SSL CA bundle not found: $value");
}
$httpRequest->caCert = $value;
}
break;
case 'decode_content':
break;
case 'save_to':
break;
case 'timeout':
$httpRequest->timeout = $value * 1000;
break;
case 'connect_timeout':
$httpRequest->connectTimeout = $value * 1000;
break;
case 'proxy':
if (!\is_array($value))
{
$uri = new Uri($value);
}
elseif (isset($request['scheme']))
{
$scheme = $request['scheme'];
if (isset($value[$scheme]))
{
$uri = new Uri($value[$scheme]);
}
else
{
break;
}
}
$httpRequest->proxy($uri->getHost(), Uri::getServerPort($uri), $uri->getScheme());
break;
case 'cert':
if (\is_array($value))
{
$httpRequest->certPassword = $value[1];
$value = $value[0];
}
if (!file_exists($value))
{
throw new \InvalidArgumentException("SSL certificate not found: {$value}");
}
$httpRequest->certType = $value;
break;
case 'ssl_key':
if (\is_array($value))
{
$httpRequest->keyPassword = $value[1];
// $options[CURLOPT_SSLKEYPASSWD] = $value[1];
$value = $value[0];
}
if (!file_exists($value))
{
throw new \InvalidArgumentException("SSL private key not found: {$value}");
}
$httpRequest->keyPath = $value;
break;
case 'progress':
break;
case 'debug':
break;
}
}
// headers
foreach ($request['headers'] as $name => $list)
{
$httpRequest->header($name, implode(', ', $list));
}
if (isset($httpRequest->headers['Content-Length']))
{
unset($httpRequest->headers['Content-Length']);
}
// request
$method = $request['http_method'] ?? 'GET';
$url = Core::url($request);
if (isset($request['client']['curl'][\CURLOPT_PORT]))
{
$uri = new Uri($url);
$uri = $uri->withPort($request['client']['curl'][\CURLOPT_PORT]);
$url = (string) $uri;
}
if (isset($request['client']['curl'][\CURLOPT_USERPWD]))
{
$httpRequest->userPwd(...explode(':', $request['client']['curl'][\CURLOPT_USERPWD], 2));
}
$body = Core::body($request);
$httpRequest->url = $url;
$httpRequest->requestBody((string) $body);
$yurunRequest = $httpRequest->buildRequest(null, null, $method);
return YurunHttp::send($yurunRequest, Coroutine::getuid() > -1 ? \Yurun\Util\YurunHttp\Handler\Swoole::class : \Yurun\Util\YurunHttp\Handler\Curl::class);
}
/**
* 获取响应数组.
*
* @param \Yurun\Util\HttpRequest $httpRequest
* @param \Yurun\Util\YurunHttp\Http\Response $yurunResponse
*
* @return array
*/
protected function getResponse(HttpRequest $httpRequest, Response $yurunResponse): array
{
$uri = new Uri($httpRequest->url);
$transferStatus = [
'url' => $httpRequest->url,
'content_type' => $yurunResponse->getHeaderLine('content-type'),
'http_code' => $yurunResponse->getStatusCode(),
'header_size' => 0,
'request_size' => 0,
'filetime' => 0,
'ssl_verify_result' => true,
'redirect_count' => 0,
'total_time' => $yurunResponse->totalTime(),
'namelookup_time' => 0,
'connect_time' => 0,
'pretransfer_time' => 0,
'size_upload' => 0,
'size_download' => 0,
'speed_download' => 0,
'speed_upload' => 0,
'download_content_length' => 0,
'upload_content_length' => 0,
'starttransfer_time' => 0,
'redirect_time' => 0,
'certinfo' => '',
'primary_ip' => $uri->getHost(),
'primary_port' => Uri::getServerPort($uri),
'local_ip' => '127.0.0.1',
'local_port' => 12345,
];
if (!$yurunResponse->success)
{
$error = new RingException($yurunResponse->getError());
}
$version = $yurunResponse->getProtocolVersion();
$status = $yurunResponse->getStatusCode();
$reason = $yurunResponse->getReasonPhrase();
$body = fopen('php://temp', 'r+');
fwrite($body, (string) $yurunResponse->getBody());
fseek($body, 0);
$response = [
'curl' => [
'errno' => 0,
'error' => '',
],
'transfer_stats' => $transferStatus,
'effective_url' => $transferStatus['url'],
'headers' => $yurunResponse->getHeaders(),
'version' => $version,
'status' => $status,
'reason' => $reason,
'body' => $body,
];
if (isset($error))
{
$response['error'] = $error;
}
return $response;
}
}