改名
This commit is contained in:
+1
-3
@@ -35,9 +35,7 @@
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kiri\\": "kiri-engine/",
|
||||
"Http\\Message\\": "http-message/",
|
||||
"Http\\Coroutine\\": "http-coroutine/",
|
||||
"Http\\Handler\\": "http-handler/",
|
||||
"Http\\": "http-core/",
|
||||
"Server\\": "http-server/",
|
||||
"Gii\\": "kiri-gii/",
|
||||
"Annotation\\": "kiri-note/"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
|
||||
|
||||
use Swoole\Coroutine;
|
||||
|
||||
abstract class BaseContext
|
||||
{
|
||||
protected static array $pool = [];
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
use Http\Handler\Handler as CHl;
|
||||
use Http\Message\ServerRequest;
|
||||
use Kiri\Core\Help;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
|
||||
abstract class Handler implements RequestHandlerInterface
|
||||
{
|
||||
|
||||
protected int $offset = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param CHl $handler
|
||||
* @param array|null $middlewares
|
||||
*/
|
||||
public function __construct(public CHl $handler, public ?array $middlewares)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function execute(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
if (empty($this->middlewares) || !isset($this->middlewares[$this->offset])) {
|
||||
return $this->dispatcher($request);
|
||||
}
|
||||
|
||||
$middleware = $this->middlewares[$this->offset];
|
||||
if (!($middleware instanceof MiddlewareInterface)) {
|
||||
throw new Exception('get_implements_class($middleware) not found method process.');
|
||||
}
|
||||
|
||||
$this->offset++;
|
||||
|
||||
return $middleware->process($request, $this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function dispatcher(ServerRequestInterface $request): mixed
|
||||
{
|
||||
$response = call_user_func($this->handler->callback, ...$this->handler->params);
|
||||
if (!($response instanceof ResponseInterface)) {
|
||||
$response = $this->transferToResponse($response);
|
||||
}
|
||||
$response->withHeader('Run-Time', $this->_runTime($request));
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ServerRequest $request
|
||||
* @return float
|
||||
*/
|
||||
private function _runTime(ServerRequestInterface $request): float
|
||||
{
|
||||
$float = microtime(true) - time();
|
||||
|
||||
$serverParams = $request->getServerParams();
|
||||
|
||||
$rTime = $serverParams['request_time_float'] - $serverParams['request_time'];
|
||||
|
||||
return round($float - $rTime, 6);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $responseData
|
||||
* @return \Server\Constrict\ResponseInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
private function transferToResponse(mixed $responseData): ResponseInterface
|
||||
{
|
||||
$interface = response()->withStatus(200);
|
||||
if (!$interface->hasContentType()) {
|
||||
$interface->withContentType('application/json;charset=utf-8');
|
||||
}
|
||||
if (str_contains($interface->getContentType(), 'xml')) {
|
||||
if (is_object($responseData)) {
|
||||
$responseData = get_object_vars($responseData);
|
||||
}
|
||||
$interface->getBody()->write(Help::toXml($responseData));
|
||||
} else if (is_array($responseData)) {
|
||||
$interface->getBody()->write(json_encode($responseData));
|
||||
} else {
|
||||
$interface->getBody()->write((string)$responseData);
|
||||
}
|
||||
return $interface;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
use Closure;
|
||||
|
||||
class HandlerManager
|
||||
{
|
||||
|
||||
|
||||
private static array $handlers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param \Http\Handler\Handler|Closure $handler
|
||||
*/
|
||||
public static function add(string $path, string $method, \Http\Handler\Handler|Closure $handler)
|
||||
{
|
||||
if (!isset(static::$handlers[$path])) {
|
||||
static::$handlers[$path] = [];
|
||||
}
|
||||
static::$handlers[$path][$method] = $handler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param $method
|
||||
* @return null|int|array|Closure
|
||||
*/
|
||||
public static function get($path, $method): null|int|\Http\Handler\Handler|Closure
|
||||
{
|
||||
if (!isset(static::$handlers[$path])) {
|
||||
return null;
|
||||
}
|
||||
$array = static::$handlers[$path][$method] ?? null;
|
||||
if (is_null($array)) {
|
||||
return 405;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getHandlers(): array
|
||||
{
|
||||
return static::$handlers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function dump(): array
|
||||
{
|
||||
$array = [];
|
||||
foreach (static::$handlers as $path => $handlers) {
|
||||
$array[] = [
|
||||
'path' => $path,
|
||||
'method' => implode(',', array_keys($handlers))
|
||||
];
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Component;
|
||||
use Kiri\Kiri;
|
||||
|
||||
|
||||
/**
|
||||
* Class HttpService
|
||||
* @package Http\Abstracts
|
||||
*/
|
||||
abstract class HttpService extends Component
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $message
|
||||
* @param string $category
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function write($message, string $category = 'app')
|
||||
{
|
||||
$logger = Kiri::app()->getLogger();
|
||||
$logger->write($message, $category);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __get($name): mixed
|
||||
{
|
||||
if (method_exists($this, $name)) {
|
||||
return $this->{$name}();
|
||||
}
|
||||
$handler = 'get' . ucfirst($name);
|
||||
if (method_exists($this, $handler)) {
|
||||
return $this->{$handler}();
|
||||
}
|
||||
if (property_exists($this, $name)) {
|
||||
return $this->$name;
|
||||
}
|
||||
$message = sprintf('method %s::%s not exists.', static::class, $name);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract class Middleware implements MiddlewareInterface
|
||||
{
|
||||
|
||||
|
||||
#[Inject(ResponseInterface::class)]
|
||||
public ResponseInterface $response;
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Http\Handler\Abstracts;
|
||||
|
||||
|
||||
use Closure;
|
||||
use Co\Iterator;
|
||||
use Kiri\Abstracts\BaseObject;
|
||||
|
||||
|
||||
/**
|
||||
* Class MiddlewareManager
|
||||
* @package Http\Route
|
||||
*/
|
||||
class MiddlewareManager extends BaseObject
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var array<string, Iterator>
|
||||
*/
|
||||
private static array $_middlewares = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @param array|string|null $middlewares
|
||||
* @return bool
|
||||
*/
|
||||
public static function add($class, $method, array|string|null $middlewares): bool
|
||||
{
|
||||
[$class, $method] = static::setDefault($class, $method);
|
||||
if (empty($middlewares)) {
|
||||
return false;
|
||||
}
|
||||
if (is_string($middlewares)) {
|
||||
$middlewares = [$middlewares];
|
||||
}
|
||||
$source = &static::$_middlewares[$class][$method];
|
||||
foreach ($middlewares as $middleware) {
|
||||
$middleware = di($middleware);
|
||||
if (in_array($middleware, $source)) {
|
||||
continue;
|
||||
}
|
||||
$source[] = $middleware;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @param $method
|
||||
* @return array
|
||||
*/
|
||||
private static function setDefault($class, $method): array
|
||||
{
|
||||
if (is_object($class)) {
|
||||
$class = $class::class;
|
||||
}
|
||||
if (!isset(static::$_middlewares[$class])) {
|
||||
static::$_middlewares[$class] = [];
|
||||
}
|
||||
if (!isset(static::$_middlewares[$class][$method])) {
|
||||
static::$_middlewares[$class][$method] = [];
|
||||
}
|
||||
return [$class, $method];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $handler
|
||||
* @return Iterator|null
|
||||
*/
|
||||
public static function get($handler): ?array
|
||||
{
|
||||
if (!($handler instanceof Closure)) {
|
||||
return static::$_middlewares[$handler[0]][$handler[1]] ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler\Annotation;
|
||||
|
||||
use Annotation\Attribute;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_CLASS)] class ControllerTarget extends Attribute
|
||||
{
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
|
||||
/**
|
||||
* Interface AuthIdentity
|
||||
* @package Kiri\Kiri\Http
|
||||
*/
|
||||
interface AuthIdentity
|
||||
{
|
||||
|
||||
|
||||
public function getIdentity();
|
||||
|
||||
|
||||
/**
|
||||
* @return string|int
|
||||
* 获取唯一识别码
|
||||
*/
|
||||
public function getUniqueId(): string|int;
|
||||
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Http\Handler\Abstracts\BaseContext;
|
||||
use Swoole\Coroutine;
|
||||
|
||||
/**
|
||||
* Class Context
|
||||
* @package Yoc\http
|
||||
*/
|
||||
class Context extends BaseContext
|
||||
{
|
||||
|
||||
protected static array $_contents = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param $context
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setContext($id, $context, $coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::$_contents[$id] = $context;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param int $value
|
||||
* @param null $coroutineId
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function increment($id, int $value = 1, $coroutineId = null): bool|int
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
Coroutine::getContext($coroutineId)[$id] = 0;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] += $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param int $value
|
||||
* @param null $coroutineId
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function decrement($id, int $value = 1, $coroutineId = null): bool|int
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
Coroutine::getContext($coroutineId)[$id] = 0;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] -= $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getContext($id, $default = null, $coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::loadByStatic($id, $default);
|
||||
}
|
||||
return static::loadByContext($id, $default, $coroutineId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
private static function loadByContext($id, $default = null, $coroutineId = null): mixed
|
||||
{
|
||||
return Coroutine::getContext($coroutineId)[$id] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
private static function loadByStatic($id, $default = null): mixed
|
||||
{
|
||||
return static::$_contents[$id] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getAllContext($coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return Coroutine::getContext($coroutineId) ?? [];
|
||||
} else {
|
||||
return static::$_contents ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param null $coroutineId
|
||||
*/
|
||||
public static function remove(string $id, $coroutineId = null)
|
||||
{
|
||||
if (!static::hasContext($id, $coroutineId)) {
|
||||
return;
|
||||
}
|
||||
if (Coroutine::getCid() === -1) {
|
||||
unset(static::$_contents[$id]);
|
||||
} else {
|
||||
unset(Coroutine::getContext($coroutineId)[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @param null $coroutineId
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasContext($id, $key = null, $coroutineId = null): bool
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::searchByStatic($id, $key);
|
||||
}
|
||||
return static::searchByCoroutine($id, $key, $coroutineId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @return bool
|
||||
*/
|
||||
private static function searchByStatic($id, $key = null): bool
|
||||
{
|
||||
if (!isset(static::$_contents[$id])) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($key) && !isset(static::$_contents[$id][$key])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @param null $coroutineId
|
||||
* @return bool
|
||||
*/
|
||||
private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
return false;
|
||||
}
|
||||
if ($key !== null) {
|
||||
return isset((Coroutine::getContext($coroutineId)[$id] ?? [])[$key]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function inCoroutine(): bool
|
||||
{
|
||||
return Coroutine::getCid() !== -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
|
||||
use Annotation\Inject;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Kiri\Application;
|
||||
use Kiri\Di\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Server\Constrict\RequestInterface;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Class WebController
|
||||
* @package Kiri\Kiri\Web
|
||||
*/
|
||||
class Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* inject di container
|
||||
*
|
||||
* @var ContainerInterface|null
|
||||
*/
|
||||
#[Inject(ContainerInterface::class)]
|
||||
public ?ContainerInterface $container = null;
|
||||
|
||||
|
||||
/**
|
||||
* inject request
|
||||
*
|
||||
* @var RequestInterface|null
|
||||
*/
|
||||
#[Inject(RequestInterface::class)]
|
||||
public ?RequestInterface $request = null;
|
||||
|
||||
|
||||
/**
|
||||
* inject response
|
||||
*
|
||||
* @var ResponseInterface|null
|
||||
*/
|
||||
#[Inject(ResponseInterface::class)]
|
||||
public ?ResponseInterface $response = null;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* inject logger
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
#[Inject(LoggerInterface::class)]
|
||||
public LoggerInterface $logger;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\Middleware;
|
||||
use Http\Message\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class CoreMiddleware extends Middleware
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param ServerRequest $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
|
||||
$requestMethod = $request->getAccessControlRequestMethod();
|
||||
$allowHeaders = $request->getAccessControlAllowHeaders();
|
||||
|
||||
if (empty($requestMethod)) $requestMethod = '*';
|
||||
if (empty($allowHeaders)) $allowHeaders = '*';
|
||||
|
||||
$this->response->withAccessControlAllowOrigin('*')->withAccessControlRequestMethod($requestMethod)
|
||||
->withAccessControlAllowHeaders($allowHeaders);
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
class DataGrip
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Exception;
|
||||
use Kiri\Core\Help;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Dispatcher extends \Http\Handler\Abstracts\Handler
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return ResponseInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
return $this->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler\Formatter;
|
||||
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\HttpService;
|
||||
use Swoole\Http\Response;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class FileFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public mixed $data;
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:51
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler\Formatter;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\HttpService;
|
||||
use Kiri\Core\Json;
|
||||
use Swoole\Http\Response;
|
||||
|
||||
/**
|
||||
* Class HtmlFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class HtmlFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public mixed $data;
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
$context = Json::encode($context);
|
||||
}
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:29
|
||||
*/
|
||||
|
||||
namespace Http\Handler\Formatter;
|
||||
|
||||
|
||||
/**
|
||||
* Interface IFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
interface IFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return static
|
||||
*/
|
||||
public function send($context): static;
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed;
|
||||
|
||||
public function clear(): void;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler\Formatter;
|
||||
|
||||
use Http\Handler\Abstracts\HttpService;
|
||||
|
||||
/**
|
||||
* Class JsonFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class JsonFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
public mixed $data;
|
||||
|
||||
public int $status = 200;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return JsonFormatter
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
$context = json_encode($context);
|
||||
}
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Handler\Formatter;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\HttpService;
|
||||
use SimpleXMLElement;
|
||||
use Swoole\Http\Response;
|
||||
|
||||
|
||||
/**
|
||||
* Class XmlFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class XmlFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public ?string $data = '';
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
// TODO: Implement send() method.
|
||||
$dom = new SimpleXMLElement('<xml/>');
|
||||
|
||||
$this->toXml($dom, $context);
|
||||
|
||||
$this->data = $dom->saveXML();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getData(): ?string
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SimpleXMLElement $dom
|
||||
* @param $data
|
||||
*/
|
||||
public function toXml(SimpleXMLElement $dom, $data)
|
||||
{
|
||||
foreach ($data as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$key = 'item' . $key;
|
||||
}
|
||||
if (is_array($val)) {
|
||||
$node = $dom->addChild($key);
|
||||
$this->toXml($node, $val);
|
||||
} else if (is_object($val)) {
|
||||
$val = get_object_vars($val);
|
||||
$node = $dom->addChild($key);
|
||||
$this->toXml($node, $val);
|
||||
} else {
|
||||
$dom->addChild($key, htmlspecialchars((string)$val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Annotation\Aspect;
|
||||
use Closure;
|
||||
use Http\Handler\Abstracts\MiddlewareManager;
|
||||
use Kiri\Di\NoteManager;
|
||||
use Kiri\Events\EventProvider;
|
||||
use Kiri\Kiri;
|
||||
use Server\Events\OnAfterWorkerStart;
|
||||
|
||||
class Handler
|
||||
{
|
||||
|
||||
|
||||
public string $route = '';
|
||||
|
||||
|
||||
public array|Closure|null $callback;
|
||||
|
||||
|
||||
public ?array $params = [];
|
||||
|
||||
|
||||
public ?array $_middlewares = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param array|Closure $callback
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function __construct(string $route, array|Closure $callback)
|
||||
{
|
||||
$this->route = $route;
|
||||
|
||||
$this->_injectParams($callback);
|
||||
|
||||
$this->callback = $callback;
|
||||
|
||||
$dispatcher = Kiri::getDi()->get(EventProvider::class);
|
||||
$dispatcher->on(OnAfterWorkerStart::class, function () {
|
||||
if ($this->callback instanceof Closure) {
|
||||
return;
|
||||
}
|
||||
$this->_middlewares = MiddlewareManager::get($this->callback);
|
||||
|
||||
$aspect = NoteManager::getSpecify_annotation(Aspect::class, $this->callback[0], $this->callback[1]);
|
||||
|
||||
$this->callback[0] = Kiri::getDi()->get($this->callback[0]);
|
||||
if (!is_null($aspect)) {
|
||||
$this->recover($aspect);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Aspect $aspect
|
||||
*/
|
||||
public function recover(Aspect $aspect)
|
||||
{
|
||||
$aspect = Kiri::getDi()->get($aspect->aspect);
|
||||
if (empty($aspect)) {
|
||||
return;
|
||||
}
|
||||
$callback = $this->callback;
|
||||
$params = $this->params;
|
||||
|
||||
$this->params = [];
|
||||
$this->callback = static function () use ($aspect, $callback, $params) {
|
||||
$aspect->before();
|
||||
$result = $aspect->invoke($callback, $params);
|
||||
$aspect->after($result);
|
||||
return $result;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array|Closure $callback
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function _injectParams(array|Closure $callback)
|
||||
{
|
||||
$container = Kiri::getDi();
|
||||
if (!($callback instanceof Closure)) {
|
||||
$this->params = $container->getMethodParameters($callback[0], $callback[1]);
|
||||
} else {
|
||||
$this->params = $container->getFunctionParameters($callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Annotation\Aspect;
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Kiri\Di\NoteManager;
|
||||
use Kiri\IAspect;
|
||||
use Kiri\Kiri;
|
||||
use ReflectionException;
|
||||
use Throwable;
|
||||
|
||||
class Pipeline
|
||||
{
|
||||
protected mixed $passable;
|
||||
|
||||
protected mixed $overall;
|
||||
|
||||
protected mixed $pipes = [];
|
||||
|
||||
|
||||
protected mixed $pipeline;
|
||||
|
||||
protected mixed $exceptionHandler;
|
||||
|
||||
/**
|
||||
* 初始数据
|
||||
* @param $passable
|
||||
* @return $this
|
||||
*/
|
||||
public function send($passable): static
|
||||
{
|
||||
$this->passable = $passable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $middle
|
||||
* @return $this
|
||||
*/
|
||||
public function overall($middle): static
|
||||
{
|
||||
$this->overall = $middle;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 调用栈
|
||||
* @param $pipes
|
||||
* @return $this
|
||||
*/
|
||||
public function through($pipes): static
|
||||
{
|
||||
if (empty($pipes)) return $this;
|
||||
if (empty($this->pipes)) {
|
||||
$this->pipes = is_array($pipes) ? $pipes : func_get_args();
|
||||
} else {
|
||||
foreach ($pipes as $pipe) {
|
||||
$this->pipes[] = $pipe;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行
|
||||
* @param callable $destination
|
||||
* @return static
|
||||
*/
|
||||
public function then(callable $destination): static
|
||||
{
|
||||
$parameters = $this->passable;
|
||||
if (!empty($this->overall)) {
|
||||
array_unshift($this->pipes, $this->overall);
|
||||
}
|
||||
if (is_array($destination)) {
|
||||
$destination = $this->aspect_caller($destination, $parameters);
|
||||
}
|
||||
$this->pipeline = array_reduce(array_reverse($this->pipes), $this->carry(),
|
||||
static function () use ($destination, $parameters) {
|
||||
return call_user_func($destination, ...$parameters);
|
||||
}
|
||||
);
|
||||
return $this->clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
private function clear(): static
|
||||
{
|
||||
$this->pipes = [];
|
||||
$this->passable = null;
|
||||
$this->overall = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $destination
|
||||
* @param $parameters
|
||||
* @return Closure|array
|
||||
*/
|
||||
private function aspect_caller($destination, $parameters): Closure|array
|
||||
{
|
||||
[$controller, $action] = $destination;
|
||||
/** @var Aspect $aop */
|
||||
$aop = NoteManager::getSpecify_annotation(Aspect::class, $controller::class, $action);
|
||||
if (!empty($aop)) {
|
||||
$aop = Kiri::getDi()->get($aop->aspect);
|
||||
$destination = static function () use ($aop, $destination, $parameters) {
|
||||
/** @var IAspect $aop */
|
||||
$aop->before();
|
||||
$aop->after($data = $aop->invoke($destination, $parameters));
|
||||
return $data;
|
||||
};
|
||||
}
|
||||
return $destination;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function interpreter($request): mixed
|
||||
{
|
||||
return call_user_func($this->pipeline, $request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置异常处理器
|
||||
* @param callable $handler
|
||||
* @return $this
|
||||
*/
|
||||
public function whenException(callable $handler): static
|
||||
{
|
||||
$this->exceptionHandler = $handler;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Closure
|
||||
*/
|
||||
protected function carry(): Closure
|
||||
{
|
||||
return static function ($stack, $pipe) {
|
||||
return static function ($passable) use ($stack, $pipe) {
|
||||
if ($pipe instanceof MiddlewareInterface) {
|
||||
$pipe = [$pipe, 'process'];
|
||||
}
|
||||
return $pipe($passable, $stack);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常处理
|
||||
* @param $passable
|
||||
* @param Throwable $e
|
||||
* @return mixed
|
||||
* @throws Throwable
|
||||
*/
|
||||
protected function handleException($passable, Throwable $e): mixed
|
||||
{
|
||||
if ($this->exceptionHandler) {
|
||||
return call_user_func($this->exceptionHandler, $passable, $e);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Handler;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\HandlerManager;
|
||||
use Http\Handler\Abstracts\MiddlewareManager;
|
||||
use Kiri\Abstracts\Logger;
|
||||
use Kiri\Kiri;
|
||||
use Throwable;
|
||||
|
||||
class Router
|
||||
{
|
||||
|
||||
|
||||
protected array $groupTack = [];
|
||||
|
||||
|
||||
protected array $methods = ['GET', 'POST', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'];
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function socket($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('SOCKET', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function post($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('POST', $route, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function get($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('GET', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function options($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('OPTIONS', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @throws
|
||||
*/
|
||||
public static function any($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
foreach ($router->methods as $method) {
|
||||
$router->addRoute($method, $route, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function delete($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('DELETE', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function head($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('HEAD', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
* @param $handler
|
||||
* @return void
|
||||
* @throws
|
||||
*/
|
||||
public static function put($route, $handler): void
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
$router->addRoute('PUT', $route, $handler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|array $method
|
||||
* @param string $route
|
||||
* @param string|Closure $closure
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function addRoute(string|array $method, string $route, string|Closure $closure)
|
||||
{
|
||||
if (!is_array($method)) $method = [$method];
|
||||
$route = $this->getPath($route);
|
||||
if (is_string($closure)) {
|
||||
$closure = explode('@', $closure);
|
||||
$closure[0] = $this->addNamespace($closure[0]);
|
||||
if (!class_exists($closure[0])) {
|
||||
return;
|
||||
}
|
||||
$this->addMiddlewares(...$closure);
|
||||
}
|
||||
foreach ($method as $value) {
|
||||
HandlerManager::add($route, $value, new Handler($route, $closure));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
* @param Closure $closure
|
||||
*/
|
||||
public static function group(array $config, Closure $closure)
|
||||
{
|
||||
$router = Kiri::getDi()->get(Router::class);
|
||||
|
||||
array_push($router->groupTack, $config);
|
||||
|
||||
call_user_func($closure, $router);
|
||||
|
||||
array_pop($router->groupTack);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @return string
|
||||
*/
|
||||
protected function getPath(string $route): string
|
||||
{
|
||||
$route = ltrim($route, '/');
|
||||
$prefix = array_column($this->groupTack, 'prefix');
|
||||
if (empty($prefix = array_filter($prefix))) {
|
||||
return '/' . $route;
|
||||
}
|
||||
return '/' . implode('/', $prefix) . '/' . $route;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $controller
|
||||
* @param $method
|
||||
*/
|
||||
protected function addMiddlewares($controller, $method)
|
||||
{
|
||||
$middleware = array_column($this->groupTack, 'middleware');
|
||||
if (empty($middleware = array_filter($middleware))) {
|
||||
return;
|
||||
}
|
||||
foreach ($middleware as $value) {
|
||||
MiddlewareManager::add($controller, $method, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @return string|null
|
||||
*/
|
||||
protected function addNamespace($class): ?string
|
||||
{
|
||||
$middleware = array_column($this->groupTack, 'namespace');
|
||||
if (empty($middleware = array_filter($middleware))) {
|
||||
return $class;
|
||||
}
|
||||
$middleware[] = $class;
|
||||
return implode('\\', array_map(function ($value) {
|
||||
return trim($value, '\\');
|
||||
}, $middleware));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function read_files()
|
||||
{
|
||||
$this->loadRouteDir(APP_PATH . 'routes');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @throws Exception
|
||||
* 加载目录下的路由文件
|
||||
*/
|
||||
private function loadRouteDir($path)
|
||||
{
|
||||
$files = glob($path . '/*');
|
||||
for ($i = 0; $i < count($files); $i++) {
|
||||
if (is_dir($files[$i])) {
|
||||
$this->loadRouteDir($files[$i]);
|
||||
} else {
|
||||
$this->loadRouterFile($files[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $files
|
||||
* @throws Exception
|
||||
*/
|
||||
private function loadRouterFile($files)
|
||||
{
|
||||
try {
|
||||
include_once "$files";
|
||||
} catch (Throwable $exception) {
|
||||
di(Logger::class)->error('router', [
|
||||
$exception->getMessage(),
|
||||
$exception->getFile(),
|
||||
$exception->getLine(),
|
||||
]);
|
||||
} finally {
|
||||
if (isset($exception)) {
|
||||
unset($exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
|
||||
class ContentType
|
||||
{
|
||||
|
||||
const X = 'application/x-';
|
||||
const OCTET_STREAM = 'application/octet-stream';
|
||||
const PDF = 'application/pdf';
|
||||
const AI = 'application/postscript';
|
||||
const ATOM_XML = 'application/atom+xml';
|
||||
const JS = 'application/ecmascript';
|
||||
const EDI_X12 = 'application/EDI-X12';
|
||||
const EDIFACT = 'application/EDIFACT';
|
||||
const JSON = 'application/json';
|
||||
const JAVASCRIPT = 'application/javascript';
|
||||
const OGG = 'application/ogg';
|
||||
const RDF = 'application/rdf+xml';
|
||||
const RSS_XML = 'application/rss+xml';
|
||||
const SOAP_XML = 'application/soap+xml';
|
||||
const WOFF = 'application/font-woff';
|
||||
const XHTML_XML = 'application/xhtml+xml';
|
||||
const XML = 'application/xml';
|
||||
const DTD = 'application/xml-dtd';
|
||||
const XOP_XML = 'application/xop+xml';
|
||||
const ZIP = 'application/zip';
|
||||
const GZIP = 'application/gzip';
|
||||
const XLS = 'application/x-xls';
|
||||
const X_001 = 'application/x-001';
|
||||
const X_301 = 'application/x-301';
|
||||
const X_906 = 'application/x-906';
|
||||
const A11 = 'application/x-a11';
|
||||
const AWF = 'application/vnd.adobe.workflow';
|
||||
const BMP = 'application/x-bmp';
|
||||
const C4T = 'application/x-c4t';
|
||||
const CAL = 'application/x-cals';
|
||||
const CDF = 'application/x-netcdf';
|
||||
const CEL = 'application/x-cel';
|
||||
const CG4 = 'application/x-g4';
|
||||
const CIT = 'application/x-cit';
|
||||
const BOT = 'application/x-bot';
|
||||
const C90 = 'application/x-c90';
|
||||
const CAT = 'application/vnd.ms-pki.seccat';
|
||||
const CDR = 'application/x-cdr';
|
||||
const CER = 'application/x-x509-ca-cert';
|
||||
const CGM = 'application/x-cgm';
|
||||
const CMX = 'application/x-cmx';
|
||||
const CRL = 'application/pkix-crl';
|
||||
const CSI = 'application/x-csi';
|
||||
const CUT = 'application/x-cut';
|
||||
const DBM = 'application/x-dbm';
|
||||
const CMP = 'application/x-cmp';
|
||||
const COT = 'application/x-cot';
|
||||
const CRT = 'application/x-x509-ca-cert';
|
||||
const DBF = 'application/x-dbf';
|
||||
const DBX = 'application/x-dbx';
|
||||
const DCX = 'application/x-dcx';
|
||||
const DGN = 'application/x-dgn';
|
||||
const DLL = 'application/x-msdownload';
|
||||
const DOT = 'application/msword';
|
||||
const DER = 'application/x-x509-ca-cert';
|
||||
const DIB = 'application/x-dib';
|
||||
const DOC = 'application/msword';
|
||||
const DRW = 'application/x-drw';
|
||||
const DWF = 'application/x-dwf';
|
||||
const DXB = 'application/x-dxb';
|
||||
const EDN = 'application/vnd.adobe.edn';
|
||||
const DWG = 'application/x-dwg';
|
||||
const DXF = 'application/x-dxf';
|
||||
const EMF = 'application/x-emf';
|
||||
const EPI = 'application/x-epi';
|
||||
const EPS = 'application/postscript';
|
||||
const EXE = 'application/x-msdownload';
|
||||
const FDF = 'application/vnd.fdf';
|
||||
const X_EPS = 'application/x-ps';
|
||||
const ETD = 'application/x-ebx';
|
||||
const FIF = 'application/fractals';
|
||||
const FRM = 'application/x-frm';
|
||||
const GBR = 'application/x-gbr';
|
||||
const G4 = 'application/x-g4';
|
||||
const GL2 = 'application/x-gl2';
|
||||
const HGL = 'application/x-hgl';
|
||||
const HPG = 'application/x-hpgl';
|
||||
const HQX = 'application/mac-binhex40';
|
||||
const HTA = 'application/hta';
|
||||
const GP4 = 'application/x-gp4';
|
||||
const HMR = 'application/x-hmr';
|
||||
const HPL = 'application/x-hpl';
|
||||
const HRF = 'application/x-hrf';
|
||||
const ICB = 'application/x-icb';
|
||||
const ICO = 'application/x-ico';
|
||||
const IG4 = 'application/x-g4';
|
||||
const III = 'application/x-iphone';
|
||||
const INS = 'application/x-internet-signup';
|
||||
const IFF = 'application/x-iff';
|
||||
const IGS = 'application/x-igs';
|
||||
const IMG = 'application/x-img';
|
||||
const ISP = 'application/x-internet-signup';
|
||||
const JPE = 'application/x-jpe';
|
||||
const X_JAVASCRIPT = 'application/x-javascript';
|
||||
const JPG = 'application/x-jpg';
|
||||
const LAR = 'application/x-laplayer-reg';
|
||||
const LATEX = 'application/x-latex';
|
||||
const LBM = 'application/x-lbm';
|
||||
const LS = 'application/x-javascript';
|
||||
const LTR = 'application/x-ltr';
|
||||
const MAN = 'application/x-troff-man';
|
||||
const MDB = 'application/msaccess';
|
||||
const MAC = 'application/x-mac';
|
||||
const X_MDB = 'application/x-mdb';
|
||||
const MFP = 'application/x-shockwave-flash';
|
||||
const MI = 'application/x-mi';
|
||||
const MIL = 'application/x-mil';
|
||||
const MOCHA = 'application/x-javascript';
|
||||
const MPD = 'application/vnd.ms-project';
|
||||
const MPP = 'application/vnd.ms-project';
|
||||
const MPT = 'application/vnd.ms-project';
|
||||
const MPW = 'application/vnd.ms-project';
|
||||
const MPX = 'application/vnd.ms-project';
|
||||
const MXP = 'application/x-mmxp';
|
||||
const NRF = 'application/x-nrf';
|
||||
const OUT = 'application/x-out';
|
||||
const P12 = 'application/x-pkcs12';
|
||||
const P7C = 'application/pkcs7-mime';
|
||||
const P7R = 'application/x-pkcs7-certreqresp';
|
||||
const PC5 = 'application/x-pc5';
|
||||
const PCL = 'application/x-pcl';
|
||||
const PDX = 'application/vnd.adobe.pdx';
|
||||
const PGL = 'application/x-pgl';
|
||||
const PKO = 'application/vnd.ms-pki.pko';
|
||||
const P10 = 'application/pkcs10';
|
||||
const P7B = 'application/x-pkcs7-certificates';
|
||||
const P7M = 'application/pkcs7-mime';
|
||||
const P7S = 'application/pkcs7-signature';
|
||||
const PCI = 'application/x-pci';
|
||||
const PCX = 'application/x-pcx';
|
||||
const PFX = 'application/x-pkcs12';
|
||||
const PIC = 'application/x-pic';
|
||||
const PL = 'application/x-perl';
|
||||
const PLT = 'application/x-plt';
|
||||
const PNG = 'application/x-png';
|
||||
const PPA = 'application/vnd.ms-powerpoint';
|
||||
const PPS = 'application/vnd.ms-powerpoint';
|
||||
const X_PPT = 'application/x-ppt';
|
||||
const PRF = 'application/pics-rules';
|
||||
const PRT = 'application/x-prt';
|
||||
const PS = 'application/postscript';
|
||||
const PWZ = 'application/vnd.ms-powerpoint';
|
||||
const RA = 'audio/vnd.rn-realaudio';
|
||||
const RAS = 'application/x-ras';
|
||||
const POT = 'application/vnd.ms-powerpoint';
|
||||
const PPM = 'application/x-ppm';
|
||||
const PPT = 'application/vnd.ms-powerpoint';
|
||||
const PR = 'application/x-pr';
|
||||
const PRN = 'application/x-prn';
|
||||
const X_PS = 'application/x-ps';
|
||||
const PTN = 'application/x-ptn';
|
||||
const RED = 'application/x-red';
|
||||
const RJS = 'application/vnd.rn-realsystem-rjs';
|
||||
const RLC = 'application/x-rlc';
|
||||
const RM = 'application/vnd.rn-realmedia';
|
||||
const RAT = 'application/rat-file';
|
||||
const REC = 'application/vnd.rn-recording';
|
||||
const RGB = 'application/x-rgb';
|
||||
const RJT = 'application/vnd.rn-realsystem-rjt';
|
||||
const RLE = 'application/x-rle';
|
||||
const RMF = 'application/vnd.adobe.rmf';
|
||||
const RMJ = 'application/vnd.rn-realsystem-rmj';
|
||||
const RMP = 'application/vnd.rn-rn_music_package';
|
||||
const RMVB = 'application/vnd.rn-realmedia-vbr';
|
||||
const RNX = 'application/vnd.rn-realplayer';
|
||||
const RPM = 'audio/x-pn-realaudio-plugin';
|
||||
const RMS = 'application/vnd.rn-realmedia-secure';
|
||||
const RMX = 'application/vnd.rn-realsystem-rmx';
|
||||
const RSML = 'application/vnd.rn-rsml';
|
||||
const RTF = 'application/msword';
|
||||
const RV = 'video/vnd.rn-realvideo';
|
||||
const SAT = 'application/x-sat';
|
||||
const SDW = 'application/x-sdw';
|
||||
const SLB = 'application/x-slb';
|
||||
const X_RTF = 'application/x-rtf';
|
||||
const SAM = 'application/x-sam';
|
||||
const SDP = 'application/sdp';
|
||||
const SIT = 'application/x-stuffit';
|
||||
const SLD = 'application/x-sld';
|
||||
const SMI = 'application/smil';
|
||||
const SMK = 'application/x-smk';
|
||||
const SMIL = 'application/smil';
|
||||
const SPC = 'application/x-pkcs7-certificates';
|
||||
const SPL = 'application/futuresplash';
|
||||
const SSM = 'application/streamingmedia';
|
||||
const STL = 'application/vnd.ms-pki.stl';
|
||||
const SST = 'application/vnd.ms-pki.certstore';
|
||||
const TDF = 'application/x-tdf';
|
||||
const TGA = 'application/x-tga';
|
||||
const STY = 'application/x-sty';
|
||||
const SWF = 'application/x-shockwave-flash';
|
||||
const TG4 = 'application/x-tg4';
|
||||
const TIF = 'application/x-tif';
|
||||
const VDX = 'application/vnd.visio';
|
||||
const VPG = 'application/x-vpeg005';
|
||||
const VSD = 'application/x-vsd';
|
||||
const VST = 'application/vnd.visio';
|
||||
const VSW = 'application/vnd.visio';
|
||||
const VTX = 'application/vnd.visio';
|
||||
const TORRENT = 'application/x-bittorrent';
|
||||
const VDA = 'application/x-vda';
|
||||
const VND_VISIO = 'application/vnd.visio';
|
||||
const VSS = 'application/vnd.visio';
|
||||
const X_VST = 'application/x-vst';
|
||||
const VSX = 'application/vnd.visio';
|
||||
const WB1 = 'application/x-wb1';
|
||||
const WB3 = 'application/x-wb3';
|
||||
const WIZ = 'application/msword';
|
||||
const WK4 = 'application/x-wk4';
|
||||
const WKS = 'application/x-wks';
|
||||
const WB2 = 'application/x-wb2';
|
||||
const WK3 = 'application/x-wk3';
|
||||
const WKQ = 'application/x-wkq';
|
||||
const WMF = 'application/x-wmf';
|
||||
const WMD = 'application/x-ms-wmd';
|
||||
const WP6 = 'application/x-wp6';
|
||||
const WPG = 'application/x-wpg';
|
||||
const WQ1 = 'application/x-wq1';
|
||||
const WRI = 'application/x-wri';
|
||||
const WS = 'application/x-ws';
|
||||
const WMZ = 'application/x-ms-wmz';
|
||||
const WPD = 'application/x-wpd';
|
||||
const WPL = 'application/vnd.ms-wpl';
|
||||
const WR1 = 'application/x-wr1';
|
||||
const WRK = 'application/x-wrk';
|
||||
const WS2 = 'application/x-ws';
|
||||
const XDP = 'application/vnd.adobe.xdp';
|
||||
const XFD = 'application/vnd.adobe.xfd';
|
||||
const XFDF = 'application/vnd.adobe.xfdf';
|
||||
const VND_MS_EXCEL = 'application/vnd.ms-excel';
|
||||
const XWD = 'application/x-xwd';
|
||||
const SIS = 'application/vnd.symbian.install';
|
||||
const X_T = 'application/x-x_t';
|
||||
const APK = 'application/vnd.android.package-archive';
|
||||
const X_B = 'application/x-x_b';
|
||||
const SISX = 'application/vnd.symbian.install';
|
||||
const IPA = 'application/vnd.iphone';
|
||||
const XAP = 'application/x-silverlight-app';
|
||||
const XLW = 'application/x-xlw';
|
||||
const XPL = 'audio/scpls';
|
||||
const ANV = 'application/x-anv';
|
||||
const UIN = 'application/x-icq';
|
||||
const H323 = 'text/h323';
|
||||
const BIZ = 'text/xml';
|
||||
const CML = 'text/xml';
|
||||
const ASA = 'text/asa';
|
||||
const ASP = 'text/asp';
|
||||
const CSS = 'text/css';
|
||||
const CSV = 'text/csv';
|
||||
const DCD = 'text/xml';
|
||||
const X_DTD = 'text/xml';
|
||||
const ENT = 'text/xml';
|
||||
const FO = 'text/xml';
|
||||
const HTC = 'text/x-component';
|
||||
const HTML = 'text/html';
|
||||
const HTX = 'text/html';
|
||||
const HTM = 'text/html';
|
||||
const HTT = 'text/webviewhtml';
|
||||
const JSP = 'text/html';
|
||||
const MATH = 'text/xml';
|
||||
const MML = 'text/xml';
|
||||
const MTX = 'text/xml';
|
||||
const PLG = 'text/html';
|
||||
const X_RDF = 'text/xml';
|
||||
const RT = 'text/vnd.rn-realtext';
|
||||
const SOL = 'text/plain';
|
||||
const SPP = 'text/xml';
|
||||
const STM = 'text/html';
|
||||
const SVG = 'text/xml';
|
||||
const TLD = 'text/xml';
|
||||
const TXT = 'text/plain纯文字内容';
|
||||
const ULS = 'text/iuls';
|
||||
const VML = 'text/xml';
|
||||
const TSD = 'text/xml';
|
||||
const VCF = 'text/x-vcard';
|
||||
const VXML = 'text/xml';
|
||||
const WML = 'text/vnd.wap.wml';
|
||||
const WSDL = 'text/xml';
|
||||
const WSC = 'text/scriptlet';
|
||||
const XDR = 'text/xml';
|
||||
const XQL = 'text/xml';
|
||||
const XSD = 'text/xml';
|
||||
const XSLT = 'text/xml';
|
||||
const X_XML = 'text/xml';
|
||||
const XQ = 'text/xml';
|
||||
const XQUERY = 'text/xml';
|
||||
const XSL = 'text/xml';
|
||||
const XHTML = 'text/html';
|
||||
const ODC = 'text/x-ms-odc';
|
||||
const R3T = 'text/vnd.rn-realtext3d';
|
||||
const SOR = 'text/plain';
|
||||
const ACP = 'audio/x-mei-aac';
|
||||
const AIF = 'audio/aiff';
|
||||
const AIFF = 'audio/aiff';
|
||||
const AIFC = 'audio/aiff';
|
||||
const AU = 'audio/basic';
|
||||
const LA1 = 'audio/x-liquid-file';
|
||||
const LAVS = 'audio/x-liquid-secure';
|
||||
const LMSFF = 'audio/x-la-lms';
|
||||
const M3U = 'audio/mpegurl';
|
||||
const MIDI = 'audio/mid';
|
||||
const MID = 'audio/mid';
|
||||
const MP2 = 'audio/mp2';
|
||||
const MP3 = 'audio/mp3';
|
||||
const MP4 = 'audio/mp4';
|
||||
const MND = 'audio/x-musicnet-download';
|
||||
const MP1 = 'audio/mp1';
|
||||
const MNS = 'audio/x-musicnet-stream';
|
||||
const MPGA = 'audio/rn-mpeg';
|
||||
const PLS = 'audio/scpls';
|
||||
const RAM = 'audio/x-pn-realaudio';
|
||||
const RMI = 'audio/mid';
|
||||
const RMM = 'audio/x-pn-realaudio';
|
||||
const SND = 'audio/basic';
|
||||
const WAV = 'audio/wav';
|
||||
const WAX = 'audio/x-ms-wax';
|
||||
const WMA = 'audio/x-ms-wma';
|
||||
const ASF = 'video/x-ms-asf';
|
||||
const ASX = 'video/x-ms-asf';
|
||||
const AVI = 'video/avi';
|
||||
const IVF = 'video/x-ivf';
|
||||
const M1V = 'video/x-mpeg';
|
||||
const M2V = 'video/x-mpeg';
|
||||
const M4E = 'video/mpeg4';
|
||||
const MOVIE = 'video/x-sgi-movie';
|
||||
const MP2V = 'video/mpeg';
|
||||
const X_MP4 = 'video/mpeg4';
|
||||
const MPA = 'video/x-mpg';
|
||||
const MPE = 'video/x-mpeg';
|
||||
const MPG = 'video/mpg';
|
||||
const MPEG = 'video/mpg';
|
||||
const MPS = 'video/x-mpeg';
|
||||
const MPV = 'video/mpg';
|
||||
const MPV2 = 'video/mpeg';
|
||||
const WM = 'video/x-ms-wm';
|
||||
const WMV = 'video/x-ms-wmv';
|
||||
const WMX = 'video/x-ms-wmx';
|
||||
const WVX = 'video/x-ms-wvx';
|
||||
const TIFF = 'image/tiff';
|
||||
const FAX = 'image/fax';
|
||||
const GIF = 'image/gif';
|
||||
const ICON = 'image/x-icon';
|
||||
const JFIF = 'image/jpeg';
|
||||
const X_JPE = 'image/jpeg';
|
||||
const JPEG = 'image/jpeg';
|
||||
const X_JPG = 'image/jpeg';
|
||||
const NET = 'image/pnetvue';
|
||||
const X_PNG = 'image/png';
|
||||
const RP = 'image/vnd.rn-realpix';
|
||||
const X_TIF = 'image/tiff';
|
||||
const X_TIFF = 'image/tiff';
|
||||
const WBMP = 'image/vnd.wap.wbmp';
|
||||
const EML = 'message/rfc822';
|
||||
const MHT = 'message/rfc822';
|
||||
const MHTML = 'message/rfc822';
|
||||
const NWS = 'message/rfc822';
|
||||
const D_907 = 'drawing/907';
|
||||
const SLK = 'drawing/x-slk';
|
||||
const TOP = 'drawing/x-top';
|
||||
const JAVA_CLASS = 'java/*';
|
||||
const JAVA = 'java/*';
|
||||
const X_DWF = 'Model/vnd.dwf';
|
||||
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
trait Message
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $version;
|
||||
|
||||
|
||||
/**
|
||||
* @var StreamInterface
|
||||
*/
|
||||
protected StreamInterface $stream;
|
||||
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected array $headers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected ?array $cookieParams = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocolVersion(): string
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $version
|
||||
* @return static
|
||||
*/
|
||||
public function withProtocolVersion($version): static
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeader($name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->headers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return string|array|null
|
||||
*/
|
||||
#[Pure] public function getHeader($name): string|null|array
|
||||
{
|
||||
if (!$this->hasHeader($name)) {
|
||||
return null;
|
||||
}
|
||||
return $this->headers[$name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function parse_curl_header(): array
|
||||
{
|
||||
$_headers = [];
|
||||
foreach ($this->headers as $key => $val) {
|
||||
$_headers[] = $key . ': ' . implode(';', $val);
|
||||
}
|
||||
return $_headers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function withData(string $headerString): static
|
||||
{
|
||||
[$headers, $body] = explode("\r\n\r\n", $headerString);
|
||||
|
||||
$this->stream = new Stream($body);
|
||||
|
||||
return $this->slip_headers($headers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $headers
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function slip_headers($headers): static
|
||||
{
|
||||
$headers = explode("\r\n", $headers);
|
||||
|
||||
$this->resolve_status(array_shift($headers));
|
||||
|
||||
foreach ($headers as $header) {
|
||||
[$key, $value] = explode(': ', $header);
|
||||
$this->withHeader($key, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $protocol
|
||||
*/
|
||||
private function resolve_status(string $protocol)
|
||||
{
|
||||
if ($this instanceof ResponseInterface) {
|
||||
[$sch, $status, $message] = explode(' ', $protocol);
|
||||
[$sch, $protocolVersion] = explode('/', $sch);
|
||||
$this->withProtocolVersion($protocolVersion)
|
||||
->withStatus(intval($status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $value
|
||||
*/
|
||||
private function addRequestHeader($key, $value)
|
||||
{
|
||||
$this->headers[$key] = [$value];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getHeaderLine($name): string|null
|
||||
{
|
||||
if ($this->hasHeader($name)) {
|
||||
return implode(';', $this->headers[$name]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getContentType(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Content-Type');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
*/
|
||||
public function withHeader($name, $value): static
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
$this->headers[$name] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
* @return static
|
||||
*/
|
||||
public function withHeaders(array $headers): static
|
||||
{
|
||||
$this->headers = $headers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
* @throws
|
||||
*/
|
||||
public function withAddedHeader($name, $value): static
|
||||
{
|
||||
if (!array_key_exists($name, $this->headers)) {
|
||||
throw new \Exception('Headers `' . $name . '` not exists.');
|
||||
}
|
||||
$this->headers[$name][] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return static
|
||||
*/
|
||||
public function withoutHeader($name): static
|
||||
{
|
||||
unset($this->headers[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return null|array
|
||||
*/
|
||||
public function getCookieParams(): ?array
|
||||
{
|
||||
return $this->cookieParams;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array|null $cookies
|
||||
* @return static
|
||||
*/
|
||||
public function withCookieParams(?array $cookies): static
|
||||
{
|
||||
$this->cookieParams = $cookies;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getBody(): StreamInterface
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param StreamInterface $body
|
||||
* @return static
|
||||
*/
|
||||
public function withBody(StreamInterface $body): static
|
||||
{
|
||||
$this->stream = $body;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Allow-Origin');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Allow-Headers');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
|
||||
protected function setStore($key, callable $callback)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Server\SInterface\OnDownloadInterface;
|
||||
|
||||
|
||||
class OnDownload extends Response implements OnDownloadInterface
|
||||
{
|
||||
|
||||
use Message;
|
||||
|
||||
|
||||
private string $path;
|
||||
private bool $isChunk;
|
||||
private int $size;
|
||||
private int $offset;
|
||||
|
||||
const IMAGES = [
|
||||
'png' => 'image/png',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'bmp' => 'image/bmp',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'tiff' => 'image/tiff',
|
||||
'svg' => 'image/svg+xml',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param false $isChunk
|
||||
* @param int $size
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function path(string $path, bool $isChunk = false, int $size = -1, int $offset = 0): OnDownload
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->isChunk = $isChunk;
|
||||
$this->size = $size;
|
||||
$this->offset = $offset;
|
||||
return $this->emitter();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function emitter(): static
|
||||
{
|
||||
$explode = explode('/', $this->path);
|
||||
$this->withHeader('Pragma', 'public');
|
||||
$this->withHeader('Expires', '0');
|
||||
$this->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
|
||||
$this->withHeader('Content-Disposition', 'attachment;filename=' . end($explode));
|
||||
$this->withHeader('Content-Type', $type = get_file_extension($this->path));
|
||||
if (!in_array($type, self::IMAGES)) {
|
||||
$this->withHeader('Content-Transfer-Encoding', 'binary');
|
||||
}
|
||||
if ($this->isChunk) {
|
||||
$resource = fopen($this->path, 'r');
|
||||
|
||||
$state = fstat($resource);
|
||||
|
||||
$this->withHeader('Content-length', $state['size']);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Response $response
|
||||
*/
|
||||
public function dispatch(mixed $response)
|
||||
{
|
||||
if (!$this->isChunk) {
|
||||
$response->sendfile($this->path);
|
||||
} else {
|
||||
$this->chunk($response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Response $response
|
||||
*/
|
||||
private function chunk(\Swoole\Http\Response $response): void
|
||||
{
|
||||
$resource = fopen($this->path, 'r');
|
||||
|
||||
$state = fstat($resource);
|
||||
|
||||
$offset = $this->offset;
|
||||
while ($file = fread($resource, $this->size)) {
|
||||
$response->write($file);
|
||||
fseek($resource, $offset);
|
||||
if ($offset >= $state['size']) {
|
||||
break;
|
||||
}
|
||||
$offset += $this->size;
|
||||
}
|
||||
$response->end();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Kiri\Core\Xml;
|
||||
|
||||
class Parse
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function data($content): mixed
|
||||
{
|
||||
if (empty($content)) {
|
||||
return null;
|
||||
}
|
||||
if (is_bool($content) || is_numeric($content)) {
|
||||
return $content;
|
||||
}
|
||||
$start = substr($content, 0, 1);
|
||||
return match ($start) {
|
||||
'<' => Xml::toArray($content),
|
||||
'[', '{' => json_decode($content, true),
|
||||
default => call_user_func(function () use ($content) {
|
||||
parse_str($content, $array);
|
||||
return $array;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Http\Handler\AuthIdentity;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Request implements RequestInterface
|
||||
{
|
||||
|
||||
use Message;
|
||||
|
||||
|
||||
/**
|
||||
* @var UriInterface
|
||||
*/
|
||||
protected UriInterface $uriInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $method;
|
||||
|
||||
|
||||
/**
|
||||
* @var AuthIdentity|null
|
||||
*/
|
||||
public ?AuthIdentity $authority = null;
|
||||
|
||||
|
||||
/**
|
||||
* @param AuthIdentity|null $authIdentity
|
||||
*/
|
||||
public function setAuthority(?AuthIdentity $authIdentity): void
|
||||
{
|
||||
$this->authority = $authIdentity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestTarget(): string
|
||||
{
|
||||
throw new BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $requestTarget
|
||||
* @return static
|
||||
*/
|
||||
public function withRequestTarget($requestTarget): static
|
||||
{
|
||||
throw new BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function withMethod($method): RequestInterface
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function isMethod(string $method): bool
|
||||
{
|
||||
return $this->method == $method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function getUri(): UriInterface
|
||||
{
|
||||
return $this->uriInterface;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param UriInterface $uri
|
||||
* @param false $preserveHost
|
||||
* @return $this|Request
|
||||
*/
|
||||
public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface
|
||||
{
|
||||
$this->uriInterface = $uri;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Kiri\Core\Help;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
use Server\SInterface\OnDownloadInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Response implements ResponseInterface
|
||||
{
|
||||
|
||||
|
||||
use Message;
|
||||
|
||||
|
||||
const CONTENT_TYPE_HTML = 'text/html';
|
||||
|
||||
|
||||
protected string $charset = 'utf8';
|
||||
|
||||
|
||||
protected int $statusCode = 200;
|
||||
|
||||
|
||||
protected string $reasonPhrase = '';
|
||||
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->stream = new Stream();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
* @param string $reasonPhrase
|
||||
* @return $this|Response
|
||||
*/
|
||||
public function withStatus($code, $reasonPhrase = ''): static
|
||||
{
|
||||
$this->statusCode = $code;
|
||||
$this->reasonPhrase = $reasonPhrase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase(): string
|
||||
{
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Allow-Origin');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Allow-Headers');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string
|
||||
{
|
||||
return $this->getHeaderLine('Access-Control-Request-Method');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return Response
|
||||
*/
|
||||
public function withContentType(string $type): static
|
||||
{
|
||||
return $this->withHeader('Content-Type', $type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
#[Pure] public function hasContentType(): bool
|
||||
{
|
||||
return $this->hasHeader('Content-Type');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return Response
|
||||
*/
|
||||
public function withAccessControlAllowHeaders(?string $value): static
|
||||
{
|
||||
return $this->withHeader('Access-Control-Allow-Headers', $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return Response
|
||||
*/
|
||||
public function withAccessControlRequestMethod(?string $value): static
|
||||
{
|
||||
return $this->withHeader('Access-Control-Request-Method', $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return Response
|
||||
*/
|
||||
public function withAccessControlAllowOrigin(?string $value): static
|
||||
{
|
||||
return $this->withHeader('Access-Control-Allow-Origin', $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param string $contentType
|
||||
* @return static
|
||||
*/
|
||||
public function json($data, string $contentType = 'application/json'): static
|
||||
{
|
||||
$this->stream->write(json_encode($data));
|
||||
|
||||
return $this->withContentType($contentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param string $contentType
|
||||
* @return static
|
||||
*/
|
||||
public function html($data, string $contentType = 'text/html'): static
|
||||
{
|
||||
if (!is_string($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
|
||||
$this->stream->write((string)$data);
|
||||
|
||||
return $this->withContentType($contentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param string $contentType
|
||||
* @return static
|
||||
*/
|
||||
public function xml($data, string $contentType = 'application/xml'): static
|
||||
{
|
||||
$this->stream->write(Help::toXml($data));
|
||||
|
||||
return $this->withContentType($contentType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $charset
|
||||
* @return $this
|
||||
*/
|
||||
public function withCharset(string $charset): static
|
||||
{
|
||||
$type = explode('charset', $this->getContentType())[0];
|
||||
$this->withContentType(
|
||||
rtrim($type,';') . ';charset=' . $charset
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param bool $isChunk
|
||||
* @param int $size
|
||||
* @param int $offset
|
||||
* @return OnDownloadInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function file($path, bool $isChunk = false, int $size = -1, int $offset = 0): OnDownloadInterface
|
||||
{
|
||||
$path = realpath($path);
|
||||
if (!file_exists($path) || !is_readable($path)) {
|
||||
throw new Exception('Cannot read file "' . $path . '", no permission');
|
||||
}
|
||||
return (new OnDownload())->path($path, $isChunk, $size, $offset);
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Http\Handler\Context;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ServerRequest extends Request implements ServerRequestInterface
|
||||
{
|
||||
|
||||
|
||||
const PARSE_BODY = 'with.parsed.body.callback';
|
||||
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected ?array $parsedBody = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected ?array $serverParams;
|
||||
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected ?array $queryParams;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected ?array $uploadedFiles;
|
||||
|
||||
|
||||
protected \Swoole\Http\Request $serverTarget;
|
||||
|
||||
|
||||
/**
|
||||
* @param array $server
|
||||
* @return static
|
||||
*/
|
||||
public function withServerParams(array $server): static
|
||||
{
|
||||
$this->serverParams = $server;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $server
|
||||
* @return static
|
||||
*/
|
||||
public function withServerTarget(\Swoole\Http\Request $server): static
|
||||
{
|
||||
$this->serverTarget = $server;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $request
|
||||
* @return static|ServerRequestInterface
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function createServerRequest(\Swoole\Http\Request $request): static|ServerRequestInterface
|
||||
{
|
||||
$serverRequest = new ServerRequest();
|
||||
$serverRequest->withData($request->getData());
|
||||
$serverRequest->withServerParams($request->server);
|
||||
$serverRequest->withServerTarget($request);
|
||||
$serverRequest->withCookieParams($request->cookie);
|
||||
$serverRequest->withUri(Uri::parseUri($request));
|
||||
$serverRequest->withQueryParams($request->get ?? []);
|
||||
$serverRequest->withUploadedFiles($request->files ?? []);
|
||||
$serverRequest->withMethod($request->getMethod());
|
||||
$serverRequest->withParsedBody($request->post);
|
||||
return $serverRequest;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return null|array
|
||||
*/
|
||||
public function getServerParams(): ?array
|
||||
{
|
||||
return $this->serverParams;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function getQueryParams(): ?array
|
||||
{
|
||||
return $this->queryParams;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function withQueryParams(array $query): ServerRequestInterface
|
||||
{
|
||||
$this->queryParams = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function getUploadedFiles(): ?array
|
||||
{
|
||||
return $this->uploadedFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $uploadedFiles
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface
|
||||
{
|
||||
$this->uploadedFiles = $uploadedFiles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|object|null
|
||||
*/
|
||||
public function getParsedBody(): object|array|null
|
||||
{
|
||||
if (empty($this->parsedBody)) {
|
||||
$callback = Context::getContext(self::PARSE_BODY);
|
||||
|
||||
$this->parsedBody = $callback($this->getBody(), $this->serverTarget->post);
|
||||
}
|
||||
return $this->parsedBody;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array|object|null $data
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function withParsedBody($data): ServerRequestInterface
|
||||
{
|
||||
$functions = function (StreamInterface $stream) use ($data) {
|
||||
$content = Parse::data($stream->getContents());
|
||||
if (!empty($content)) {
|
||||
return $content;
|
||||
}
|
||||
return $data;
|
||||
};
|
||||
Context::setContext(self::PARSE_BODY, $functions);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null): mixed
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function withAttribute($name, $value): ServerRequestInterface
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return ServerRequestInterface
|
||||
*/
|
||||
public function withoutAttribute($name): ServerRequestInterface
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
class StatusCode
|
||||
{
|
||||
|
||||
const CODE_100 = 100;
|
||||
const CODE_101 = 101;
|
||||
const CODE_200 = 200;
|
||||
const CODE_201 = 201;
|
||||
const CODE_202 = 202;
|
||||
const CODE_203 = 203;
|
||||
const CODE_204 = 204;
|
||||
const CODE_205 = 205;
|
||||
const CODE_206 = 206;
|
||||
const CODE_300 = 300;
|
||||
const CODE_301 = 301;
|
||||
const CODE_302 = 302;
|
||||
const CODE_303 = 303;
|
||||
const CODE_304 = 304;
|
||||
const CODE_305 = 305;
|
||||
const CODE_307 = 307;
|
||||
const CODE_400 = 400;
|
||||
const CODE_401 = 401;
|
||||
const CODE_403 = 403;
|
||||
const CODE_404 = 404;
|
||||
const CODE_405 = 405;
|
||||
const CODE_406 = 406;
|
||||
const CODE_407 = 407;
|
||||
const CODE_408 = 408;
|
||||
const CODE_409 = 409;
|
||||
const CODE_410 = 410;
|
||||
const CODE_411 = 411;
|
||||
const CODE_412 = 412;
|
||||
const CODE_413 = 413;
|
||||
const CODE_414 = 414;
|
||||
const CODE_415 = 415;
|
||||
const CODE_416 = 416;
|
||||
const CODE_417 = 417;
|
||||
const CODE_423 = 423;
|
||||
const CODE_500 = 500;
|
||||
const CODE_501 = 501;
|
||||
const CODE_502 = 502;
|
||||
const CODE_503 = 503;
|
||||
const CODE_504 = 504;
|
||||
const CODE_505 = 505;
|
||||
|
||||
|
||||
const CODE_STATUS = [
|
||||
self::CODE_100 => 'Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新)',
|
||||
self::CODE_101 => 'Switching Protocols 服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新)',
|
||||
self::CODE_200 => '(成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。',
|
||||
self::CODE_201 => '(已创建) 请求成功并且服务器创建了新的资源。',
|
||||
self::CODE_202 => '(已接受) 服务器已接受请求,但尚未处理。',
|
||||
self::CODE_203 => '(非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。',
|
||||
self::CODE_204 => '(无内容) 服务器成功处理了请求,但没有返回任何内容。',
|
||||
self::CODE_205 => '(重置内容) 服务器成功处理了请求,但没有返回任何内容。',
|
||||
self::CODE_206 => '(部分内容) 服务器成功处理了部分 GET 请求。',
|
||||
self::CODE_300 => '(多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。',
|
||||
self::CODE_301 => '(永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。',
|
||||
self::CODE_302 => '(临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。',
|
||||
self::CODE_303 => '(查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。',
|
||||
self::CODE_304 => '(未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。',
|
||||
self::CODE_305 => '(使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。',
|
||||
self::CODE_307 => '(临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。',
|
||||
self::CODE_400 => '(错误请求) 服务器不理解请求的语法。',
|
||||
self::CODE_401 => '(未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。',
|
||||
self::CODE_403 => '(禁止) 服务器拒绝请求。',
|
||||
self::CODE_404 => '(未找到) 服务器找不到请求的网页。',
|
||||
self::CODE_405 => '(方法禁用) 禁用请求中指定的方法。',
|
||||
self::CODE_406 => '(不接受) 无法使用请求的内容特性响应请求的网页。',
|
||||
self::CODE_407 => '(需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。',
|
||||
self::CODE_408 => '(请求超时) 服务器等候请求时发生超时。',
|
||||
self::CODE_409 => '(冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。',
|
||||
self::CODE_410 => '(已删除) 如果请求的资源已永久删除,服务器就会返回此响应。',
|
||||
self::CODE_411 => '(需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。',
|
||||
self::CODE_412 => '(未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。',
|
||||
self::CODE_413 => '(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。',
|
||||
self::CODE_414 => '(请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。',
|
||||
self::CODE_415 => '(不支持的媒体类型) 请求的格式不受请求页面的支持。',
|
||||
self::CODE_416 => '(请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。',
|
||||
self::CODE_417 => '(未满足期望值) 服务器未满足"期望"请求标头字段的要求。',
|
||||
self::CODE_423 => ' 锁定的错误。',
|
||||
self::CODE_500 => '(服务器内部错误) 服务器遇到错误,无法完成请求。',
|
||||
self::CODE_501 => '(尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。',
|
||||
self::CODE_502 => '(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。',
|
||||
self::CODE_503 => '(服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。',
|
||||
self::CODE_504 => '(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。',
|
||||
self::CODE_505 => '(HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。',
|
||||
];
|
||||
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
|
||||
class Stream implements StreamInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var string|resource
|
||||
*/
|
||||
private mixed $content = '';
|
||||
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private int $size = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $stream
|
||||
*/
|
||||
public function __construct(mixed $stream = '')
|
||||
{
|
||||
$this->content = $stream;
|
||||
if (!is_resource($stream)) {
|
||||
$this->size = strlen($stream);
|
||||
} else {
|
||||
$state = fstat($this->content);
|
||||
if ($state) {
|
||||
$this->size = $state['size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return resource|null
|
||||
*/
|
||||
public function detach()
|
||||
{
|
||||
if (!is_resource($this->content)) {
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
$steam = stream_context_create();
|
||||
stream_copy_to_stream($this->content, $steam);
|
||||
return $steam;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool|int
|
||||
*/
|
||||
public function tell(): bool|int
|
||||
{
|
||||
if (!is_resource($this->content)) {
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
return ftell($this->content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function eof(): bool
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSeekable(): bool
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $whence
|
||||
*/
|
||||
public function seek($offset, $whence = SEEK_SET)
|
||||
{
|
||||
if (!is_resource($this->content)) {
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
fseek($this->content, $offset, $whence);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable(): bool
|
||||
{
|
||||
if (!is_resource($this->content)) {
|
||||
return true;
|
||||
}
|
||||
if (is_writable($this->content)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
public function write($string): int
|
||||
{
|
||||
if (is_resource($this->content)) {
|
||||
fwrite($this->content, $string);
|
||||
$state = fstat($this->content);
|
||||
if ($state) {
|
||||
$this->size = $state['size'];
|
||||
}
|
||||
} else {
|
||||
$this->content = $string;
|
||||
$this->size = strlen($string);
|
||||
}
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable(): bool
|
||||
{
|
||||
if (!is_resource($this->content)) {
|
||||
return true;
|
||||
}
|
||||
if (is_readable($this->content)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return false|string
|
||||
*/
|
||||
public function read($length): bool|string
|
||||
{
|
||||
if (is_resource($this->content)) {
|
||||
return fread($this->content, $length);
|
||||
} else {
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|bool
|
||||
*/
|
||||
public function getContents(): string|bool
|
||||
{
|
||||
if (is_resource($this->content)) {
|
||||
return stream_get_contents($this->content);
|
||||
} else {
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param null $key
|
||||
* @return array
|
||||
*/
|
||||
#[ArrayShape([
|
||||
"timed_out" => "bool",
|
||||
"blocked" => "bool",
|
||||
"eof" => "bool",
|
||||
"unread_bytes" => "int",
|
||||
"stream_type" => "string",
|
||||
"wrapper_type" => "string",
|
||||
"wrapper_data" => "mixed",
|
||||
"mode" => "string",
|
||||
"seekable" => "bool",
|
||||
"uri" => "string",
|
||||
"crypto" => "array",
|
||||
"mediatype" => "string",
|
||||
])]
|
||||
public function getMetadata($key = null): array
|
||||
{
|
||||
if (is_resource($this->content)) {
|
||||
return stream_get_meta_data($this->content);
|
||||
}
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
|
||||
class Uploaded implements UploadedFileInterface
|
||||
{
|
||||
|
||||
const ERROR = [
|
||||
0 => "There is no error, the file uploaded with success",
|
||||
1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini",
|
||||
2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
|
||||
3 => "The uploaded file was only partially uploaded",
|
||||
4 => "No file was uploaded",
|
||||
6 => "Missing a temporary folder"
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private mixed $stream;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $tmp_name
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param int $size
|
||||
* @param int $error
|
||||
*/
|
||||
public function __construct(
|
||||
public string $tmp_name,
|
||||
public string $name,
|
||||
public string $type,
|
||||
public int $size,
|
||||
public int $error
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getStream(): StreamInterface
|
||||
{
|
||||
if ($this->stream instanceof Stream) {
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
$this->stream = new Stream(fopen($this->tmp_name, 'r+'));
|
||||
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
* @return StreamInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
public function moveTo($targetPath): StreamInterface
|
||||
{
|
||||
@move_uploaded_file($this->tmp_name, $targetPath);
|
||||
if (!file_exists($targetPath)) {
|
||||
throw new Exception('File save fail.');
|
||||
}
|
||||
|
||||
if ($this->stream instanceof Stream) {
|
||||
$this->stream->close();
|
||||
$this->stream = null;
|
||||
}
|
||||
|
||||
$this->tmp_name = $targetPath;
|
||||
return $this->getStream();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getError(): int
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientFilename(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClientMediaType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Message;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Swoole\Http\Request;
|
||||
|
||||
|
||||
class Uri implements UriInterface
|
||||
{
|
||||
|
||||
|
||||
protected string $scheme = '';
|
||||
protected string $host = '';
|
||||
protected string $path = '';
|
||||
protected string $fragment = '';
|
||||
protected int $port = 80;
|
||||
|
||||
|
||||
protected string $queryString = '';
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme(): string
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthority(): string
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUserInfo(): string
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getPort(): ?int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQuery(): string
|
||||
{
|
||||
return $this->queryString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFragment(): string
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @return $this|Uri
|
||||
*/
|
||||
public function withScheme($scheme): UriInterface
|
||||
{
|
||||
$this->scheme = $scheme;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param null $password
|
||||
* @return Uri
|
||||
*/
|
||||
public function withUserInfo($user, $password = null): UriInterface
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @return $this|Uri
|
||||
*/
|
||||
public function withHost($host): UriInterface
|
||||
{
|
||||
$this->host = $host;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int|null $port
|
||||
* @return $this|Uri
|
||||
*/
|
||||
public function withPort($port): UriInterface
|
||||
{
|
||||
$this->port = $port;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return $this|Uri
|
||||
*/
|
||||
public function withPath($path): UriInterface
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @return $this|Uri
|
||||
*/
|
||||
public function withQuery($query): UriInterface
|
||||
{
|
||||
$this->queryString = $query;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $fragment
|
||||
* @return Uri
|
||||
*/
|
||||
public function withFragment($fragment): UriInterface
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$domain = sprintf('%s://%s', $this->scheme, $this->host);
|
||||
if (!in_array($this->port, [80, 443])) {
|
||||
$domain .= ':' . $this->port;
|
||||
}
|
||||
if (empty($this->query) && empty($this->fragment)) {
|
||||
return $domain . $this->path;
|
||||
}
|
||||
return sprintf('%s?%s#%s', $domain . $this->path,
|
||||
$this->queryString, $this->fragment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDefaultPort(): int
|
||||
{
|
||||
return $this->scheme == 'https' ? 443 : 80;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return UriInterface
|
||||
*/
|
||||
public static function parseUri(Request $request): UriInterface
|
||||
{
|
||||
$server = $request->server;
|
||||
$header = $request->header;
|
||||
$uri = new static();
|
||||
$uri = $uri->withScheme(!empty($server['https']) && $server['https'] !== 'off' ? 'https' : 'http');
|
||||
if (isset($request->header['x-forwarded-proto'])) {
|
||||
$uri->withScheme($request->header['x-forwarded-proto'])->withPort(443);
|
||||
}
|
||||
|
||||
$hasPort = false;
|
||||
if (isset($server['http_host'])) {
|
||||
$hostHeaderParts = explode(':', $server['http_host']);
|
||||
$uri = $uri->withHost($hostHeaderParts[0]);
|
||||
if (isset($hostHeaderParts[1])) {
|
||||
$hasPort = true;
|
||||
$uri = $uri->withPort($hostHeaderParts[1]);
|
||||
}
|
||||
} elseif (isset($server['server_name'])) {
|
||||
$uri = $uri->withHost($server['server_name']);
|
||||
} elseif (isset($server['server_addr'])) {
|
||||
$uri = $uri->withHost($server['server_addr']);
|
||||
} elseif (isset($header['host'])) {
|
||||
$hasPort = true;
|
||||
if (strpos($header['host'], ':')) {
|
||||
[$host, $port] = explode(':', $header['host'], 2);
|
||||
if ($port != $uri->getDefaultPort()) {
|
||||
$uri = $uri->withPort($port);
|
||||
}
|
||||
} else {
|
||||
$host = $header['host'];
|
||||
}
|
||||
|
||||
$uri = $uri->withHost($host);
|
||||
}
|
||||
|
||||
if (!$hasPort && isset($server['server_port'])) {
|
||||
$uri = $uri->withPort($server['server_port']);
|
||||
}
|
||||
|
||||
$hasQuery = false;
|
||||
if (isset($server['request_uri'])) {
|
||||
$requestUriParts = explode('?', $server['request_uri']);
|
||||
$uri = $uri->withPath($requestUriParts[0]);
|
||||
if (isset($requestUriParts[1])) {
|
||||
$hasQuery = true;
|
||||
$uri = $uri->withQuery($requestUriParts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasQuery && isset($server['query_string'])) {
|
||||
$uri = $uri->withQuery($server['query_string']);
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Abstracts;
|
||||
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PageNotFoundException extends \Exception
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
#[Pure] public function __construct(int $code)
|
||||
{
|
||||
parent::__construct('<h2>HTTP 404 Not Found</h2><hr><i>Powered by Swoole</i>', $code);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,6 @@ namespace Server\Abstracts;
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Abstracts\Logger;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Abstracts\Utility;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Kiri\Events\EventDispatch;
|
||||
|
||||
trait EventDispatchHelper
|
||||
{
|
||||
|
||||
/** @var EventDispatch */
|
||||
#[Inject(EventDispatch::class)]
|
||||
public EventDispatch $eventDispatch;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Abstracts\Utility;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Server\Constrict\Emitter;
|
||||
use Server\Constrict\Response as CResponse;
|
||||
use Server\Constrict\ResponseEmitter;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
trait ResponseHelper
|
||||
{
|
||||
|
||||
/** @var CResponse|mixed */
|
||||
#[Inject(CResponse::class)]
|
||||
public CResponse $response;
|
||||
|
||||
|
||||
public Emitter $responseEmitter;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Server\Constrict\ResponseInterface;
|
||||
|
||||
interface Emitter
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $response
|
||||
* @param ResponseInterface $emitter
|
||||
* @return mixed
|
||||
*/
|
||||
public function sender(mixed $response, ResponseInterface $emitter): void;
|
||||
|
||||
}
|
||||
@@ -1,509 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Http\Handler\Context;
|
||||
use Http\Handler\AuthIdentity;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Kiri\Kiri;
|
||||
use Http\Message\Response;
|
||||
use Http\Message\ServerRequest;
|
||||
use Http\Message\Uploaded;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
|
||||
class Request implements RequestInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return ServerRequest
|
||||
*/
|
||||
private function __call__(): ServerRequest
|
||||
{
|
||||
return Context::getContext(RequestInterface::class, new ServerRequest());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $name, array $arguments)
|
||||
{
|
||||
return $this->__call__()->{$name}(...$arguments);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name): mixed
|
||||
{
|
||||
// TODO: Change the autogenerated stub
|
||||
return $this->__call__()->{$name};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $request
|
||||
* @return Request
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function create(\Swoole\Http\Request $request): Request
|
||||
{
|
||||
$serverRequest = ServerRequest::createServerRequest($request);
|
||||
|
||||
Context::setContext(ResponseInterface::class, new Response());
|
||||
|
||||
Context::setContext(RequestInterface::class, $serverRequest);
|
||||
|
||||
return Kiri::getDi()->get(Request::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocolVersion(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
* @return Request
|
||||
*/
|
||||
public function withProtocolVersion($version): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($version);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \string[][]
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeader($name): bool
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string[]
|
||||
*/
|
||||
public function getHeader($name): array
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaderLine($name): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|string[] $value
|
||||
* @return Request
|
||||
*/
|
||||
public function withHeader($name, $value): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|string[] $value
|
||||
* @return Request
|
||||
*/
|
||||
public function withAddedHeader($name, $value): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return Request
|
||||
*/
|
||||
public function withoutHeader($name): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getBody(): StreamInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param StreamInterface $body
|
||||
* @return Request
|
||||
*/
|
||||
public function withBody(StreamInterface $body): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($body);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestTarget(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $requestTarget
|
||||
* @return Request
|
||||
*/
|
||||
public function withRequestTarget($requestTarget): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($requestTarget);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function isMethod(string $method): bool
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return Request
|
||||
*/
|
||||
public function withMethod($method): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function getUri(): UriInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param UriInterface $uri
|
||||
* @param false $preserveHost
|
||||
* @return Request
|
||||
*/
|
||||
public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($uri, $preserveHost);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return UploadedFileInterface|null
|
||||
*/
|
||||
public function file(string $name): ?UploadedFileInterface
|
||||
{
|
||||
$files = $this->__call__()->getUploadedFiles();
|
||||
if (empty($files) || !isset($files[$name])) {
|
||||
return null;
|
||||
}
|
||||
return new Uploaded($files[$name]['tmp_name'], $files[$name]['name'], $files[$name]['type'],
|
||||
$files[$name]['size'], $files[$name]['error']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $name
|
||||
* @param mixed|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
private function _getParsedBody(string|null $name = null, mixed $default = null): mixed
|
||||
{
|
||||
$body = $this->__call__()->getParsedBody();
|
||||
if (empty($name)) {
|
||||
return $body;
|
||||
}
|
||||
return $body[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->_getParsedBody();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool|int|string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query(string $name, bool|int|string|null $default = null): mixed
|
||||
{
|
||||
$files = $this->__call__()->getQueryParams();
|
||||
|
||||
return $files[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|bool|array|string|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function post(string $name, int|bool|array|string|null $default = null): mixed
|
||||
{
|
||||
return $this->_getParsedBody($name, $default);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return int|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function int(string $name, bool $required = false): ?int
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int) && $required) {
|
||||
throw new \Exception('Required param "' . $name . '"');
|
||||
}
|
||||
return (int)$int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return float|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function float(string $name, bool $required = false): ?float
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int) && $required) {
|
||||
throw new \Exception('Required param "' . $name . '"');
|
||||
}
|
||||
return (float)$int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return string|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function date(string $name, bool $required = false): ?string
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int) && $required) {
|
||||
throw new \Exception('Required param "' . $name . '"');
|
||||
}
|
||||
return (string)$int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return int|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function timestamp(string $name, bool $required = false): ?int
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int) && $required) {
|
||||
throw new \Exception('Required param "' . $name . '"');
|
||||
}
|
||||
return (int)$int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return string|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function string(string $name, bool $required = false): ?string
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int) && $required) {
|
||||
throw new \Exception('Required param "' . $name . '"');
|
||||
}
|
||||
return (string)$int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $default
|
||||
* @return array|null
|
||||
*/
|
||||
public function array(string $name, array $default = []): ?array
|
||||
{
|
||||
$int = $this->_getParsedBody($name);
|
||||
if (is_null($int)) {
|
||||
return $default;
|
||||
}
|
||||
return $int;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function gets(): ?array
|
||||
{
|
||||
return $this->__call__()->getQueryParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param string $sizeField
|
||||
* @param int $max
|
||||
* @return float|int
|
||||
*/
|
||||
public function offset(string $field = 'page', string $sizeField = 'size', int $max = 100): float|int
|
||||
{
|
||||
$page = $this->query($field);
|
||||
$size = $this->size($sizeField, $max);
|
||||
$offset = ($page - 1) * $size;
|
||||
if ($offset < 0) {
|
||||
$offset = 0;
|
||||
}
|
||||
return $offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param int $max
|
||||
* @return int
|
||||
*/
|
||||
public function size(string $field = 'size', int $max = 100): int
|
||||
{
|
||||
$size = $this->query($field);
|
||||
if ($size > $max) {
|
||||
$size = $max;
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function input($name, $default = null): mixed
|
||||
{
|
||||
return $this->_getParsedBody($name, $default);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
#[Pure] public function getStartTime(): float
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param AuthIdentity $authority
|
||||
*/
|
||||
public function setAuthority(AuthIdentity $authority): void
|
||||
{
|
||||
$this->__call__()->{__FUNCTION__}($authority);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
|
||||
use Http\Handler\AuthIdentity;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Http\Message\ServerRequest;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @mixin ServerRequest
|
||||
*/
|
||||
interface RequestInterface extends \Psr\Http\Message\RequestInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function isMethod(string $method): bool;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return UploadedFileInterface|null
|
||||
*/
|
||||
public function file(string $name): ?UploadedFileInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function all(): array;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|string|bool|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query(string $name, int|string|bool|null $default = null): mixed;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|string|bool|array|null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function post(string $name, int|string|bool|null|array $default = null): mixed;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return int|null
|
||||
*/
|
||||
public function int(string $name, bool $required = false): ?int;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return float|null
|
||||
*/
|
||||
public function float(string $name, bool $required = false): ?float;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return string|null
|
||||
*/
|
||||
public function date(string $name, bool $required = false): ?string;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return int|null
|
||||
*/
|
||||
public function timestamp(string $name, bool $required = false): ?int;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $required
|
||||
* @return string|null
|
||||
*/
|
||||
public function string(string $name, bool $required = false): ?string;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $default
|
||||
* @return array|null
|
||||
*/
|
||||
public function array(string $name, array $default = []): ?array;
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function gets(): ?array;
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param string $sizeField
|
||||
* @param int $max
|
||||
* @return float|int
|
||||
*/
|
||||
public function offset(string $field = 'page', string $sizeField = 'size', int $max = 100): float|int;
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param int $max
|
||||
* @return int
|
||||
*/
|
||||
public function size(string $field = 'size', int $max = 100): int;
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function input($name, $default = null): mixed;
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
#[Pure] public function getStartTime(): float;
|
||||
|
||||
/**
|
||||
* @param AuthIdentity $authority
|
||||
*/
|
||||
public function setAuthority(AuthIdentity $authority): void;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string;
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string;
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
|
||||
use Http\Handler\Context;
|
||||
use Http\Message\ContentType;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Http\Message\ServerRequest as RequestMessage;
|
||||
use Http\Message\Response as Psr7Response;
|
||||
use Server\ServerManager;
|
||||
use Server\SInterface\OnDownloadInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Class Response
|
||||
* @package Server
|
||||
*/
|
||||
class Response implements ResponseInterface
|
||||
{
|
||||
|
||||
const JSON = 'json';
|
||||
const XML = 'xml';
|
||||
const HTML = 'html';
|
||||
const FILE = 'file';
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$contentType = Config::get('response',[
|
||||
'format' => ContentType::JSON,
|
||||
'charset' => 'utf-8'
|
||||
]);
|
||||
$this->withContentType($contentType['format'] ?? ContentType::JSON)
|
||||
->withCharset($contentType['charset'] ?? 'utf-8');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $name)
|
||||
{
|
||||
return $this->__call__()->{$name};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Psr7Response
|
||||
*/
|
||||
public function __call__(): Psr7Response
|
||||
{
|
||||
return Context::getContext(ResponseInterface::class, new Psr7Response());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocolVersion(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withProtocolVersion($version): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($version);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeader($name): bool
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getHeader($name): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getHeaderLine($name): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|string[] $value
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withHeader($name, $value): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|string[] $value
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withAddedHeader($name, $value): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name, $value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withoutHeader($name): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getBody(): StreamInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param StreamInterface $body
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withBody(StreamInterface $body): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
* @param string $reasonPhrase
|
||||
* @return ResponseInterface|Psr7Response
|
||||
*/
|
||||
public function withStatus($code, $reasonPhrase = ''): ResponseInterface|Psr7Response
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($code, $reasonPhrase);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return OnDownloadInterface
|
||||
*/
|
||||
public function file(string $path): OnDownloadInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $responseData
|
||||
* @return string|array|bool|int|null
|
||||
*/
|
||||
public function _toArray($responseData): string|array|null|bool|int
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($responseData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function xml($data): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function html($data): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function json($data): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType(): string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasContentType(): bool
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withContentType(string $type): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlAllowOrigin(?string $value): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlRequestMethod(?string $value): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlAllowHeaders(?string $value): ResponseInterface
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}($value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string
|
||||
{
|
||||
return $this->__call__()->{__FUNCTION__}();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int
|
||||
{
|
||||
if (!Context::hasContext('client.id.property')) {
|
||||
$request = Context::getContext(RequestInterface::class, new RequestMessage());
|
||||
return Context::setContext('client.id.property', $request->getClientId());
|
||||
}
|
||||
return (int)Context::getContext('client.id.property');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getClientInfo(): array
|
||||
{
|
||||
if (!Context::hasContext('client.info.property')) {
|
||||
$request = Context::getContext(RequestInterface::class, new RequestMessage());
|
||||
|
||||
$server = Kiri::getDi()->get(ServerManager::class)->getServer();
|
||||
|
||||
$clientInfo = $server->getClientInfo($request->getClientId());
|
||||
|
||||
return Context::setContext('client.info.property', $clientInfo);
|
||||
}
|
||||
return Context::getContext('client.info.property');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Server\SInterface\OnDownloadInterface;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ResponseEmitter implements Emitter
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var RequestInterface
|
||||
*/
|
||||
#[Inject(RequestInterface::class)]
|
||||
public RequestInterface $request;
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Response $response
|
||||
* @param \Http\Message\Response|ResponseInterface $emitter
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sender(mixed $response, ResponseInterface|\Http\Message\Response $emitter): void
|
||||
{
|
||||
if (is_array($emitter->getHeaders())) {
|
||||
foreach ($emitter->getHeaders() as $name => $values) {
|
||||
$response->header($name, implode(';', $values));
|
||||
}
|
||||
}
|
||||
if (is_array($emitter->getCookieParams())) {
|
||||
foreach ($emitter->getCookieParams() as $name => $cookie) {
|
||||
$response->cookie($name, ...$cookie);
|
||||
}
|
||||
}
|
||||
$response->setStatusCode($emitter->getStatusCode());
|
||||
$response->header('Server', 'swoole');
|
||||
$response->header('Swoole-Version', swoole_version());
|
||||
if (!($emitter instanceof OnDownloadInterface)) {
|
||||
$response->end($emitter->getBody()->getContents());
|
||||
} else {
|
||||
$emitter->dispatch($response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Http\Message\Response;
|
||||
use Server\SInterface\OnDownloadInterface;
|
||||
|
||||
/**
|
||||
* @mixin Response
|
||||
*/
|
||||
interface ResponseInterface extends \Psr\Http\Message\ResponseInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return OnDownloadInterface
|
||||
*/
|
||||
public function file(string $path): OnDownloadInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function xml($data): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function html($data): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function json($data): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentType(): ?string;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasContentType(): bool;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withContentType(string $type): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param ?string $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlAllowOrigin(?string $value): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param ?string $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlRequestMethod(?string $value): ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @param ?string $value
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withAccessControlAllowHeaders(?string $value): ResponseInterface;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowOrigin(): ?string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlAllowHeaders(): ?string;
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getAccessControlRequestMethod(): ?string;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Exception;
|
||||
use Http\Handler\Formatter\FileFormatter;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class TcpEmitter implements Emitter
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $response
|
||||
* @param ResponseInterface $emitter
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sender(mixed $response, ResponseInterface $emitter): void
|
||||
{
|
||||
$formatter = $emitter->stream->getContents();
|
||||
if ($formatter instanceof FileFormatter) {
|
||||
$response->sendfile($emitter->getClientId(), $formatter);
|
||||
} else {
|
||||
$response->send($emitter->getClientId(), $formatter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Kiri\Exception\NotFindClassException;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class UdpEmitter implements Emitter
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $response
|
||||
* @param ResponseInterface $emitter
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sender(mixed $response, ResponseInterface $emitter): void
|
||||
{
|
||||
$clientInfo = $emitter->getClientInfo();
|
||||
$response->sendto($clientInfo['host'], $clientInfo['port'],
|
||||
$emitter->stream->getContents()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Constrict;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
use Server\ServerManager;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class WebSocketEmitter implements Emitter
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $response
|
||||
* @param ResponseInterface|\Http\Message\Response $emitter
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sender(mixed $response, ResponseInterface|\Http\Message\Response $emitter): void
|
||||
{
|
||||
$server = Kiri::getDi()->get(ServerManager::class)->getServer();
|
||||
|
||||
$server->push($response->fd, $emitter->getBody()->getContents());
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Events;
|
||||
|
||||
class OnAfterRequest
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Events;
|
||||
|
||||
class OnBeforeRequest
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
|
||||
use Http\Message\ContentType;
|
||||
use Http\Message\Stream;
|
||||
use Server\Constrict\Response;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
use Throwable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ExceptionHandlerDispatcher implements ExceptionHandlerInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Throwable $exception
|
||||
* @param Response $response
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function emit(Throwable $exception, Response $response): ResponseInterface
|
||||
{
|
||||
$response->withContentType(ContentType::HTML)->withCharset('utf-8');
|
||||
if ($exception->getCode() == 404) {
|
||||
return $response->withBody(new Stream($exception->getMessage()))
|
||||
->withStatus(404);
|
||||
}
|
||||
$code = $exception->getCode() == 0 ? 500 : $exception->getCode();
|
||||
return $response->withBody(new Stream(jTraceEx($exception, null, true)))
|
||||
->withStatus($code);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use Server\Constrict\Response;
|
||||
use Throwable;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
interface ExceptionHandlerInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Throwable $exception
|
||||
* @param Response $response
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function emit(Throwable $exception, Response $response): ResponseInterface;
|
||||
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
namespace Server\Handler;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Server\Abstracts\Server;
|
||||
use Exception;
|
||||
use Server\Events\OnAfterRequest;
|
||||
use Server\SInterface\OnPipeMessageInterface;
|
||||
use Kiri\Events\EventDispatch;
|
||||
|
||||
@@ -32,9 +31,7 @@ class OnPipeMessage extends Server
|
||||
if (!is_object($message) || !($message instanceof OnPipeMessageInterface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
call_user_func([$message, 'process'], $server, $src_worker_id);
|
||||
$this->eventDispatch->dispatch(new OnAfterRequest());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
namespace Server\Handler;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Kiri\Events\EventDispatch;
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
namespace Server\Handler;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Kiri\Events\EventDispatch;
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
namespace Server\Handler;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Kiri\Events\EventDispatch;
|
||||
@@ -1,17 +1,14 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server\Task;
|
||||
namespace Server\Handler;
|
||||
|
||||
|
||||
use Kiri\Abstracts\Config;
|
||||
use Annotation\Inject;
|
||||
use Kiri\Abstracts\Logger;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use ReflectionException;
|
||||
use Server\Constrict\Response;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
use Server\ExceptionHandlerDispatcher;
|
||||
use Server\ExceptionHandlerInterface;
|
||||
use Server\SInterface\OnTaskInterface;
|
||||
use Swoole\Server;
|
||||
|
||||
@@ -24,26 +21,8 @@ class OnServerTask
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var ExceptionHandlerInterface|null
|
||||
*/
|
||||
public ?ExceptionHandlerInterface $handler = null;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function emit(\Throwable $exception, Response $response): ResponseInterface
|
||||
{
|
||||
if ($this->handler == null) {
|
||||
$exceptionHandler = Config::get('exception.task', ExceptionHandlerDispatcher::class);
|
||||
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
|
||||
$exceptionHandler = ExceptionHandlerDispatcher::class;
|
||||
}
|
||||
$this->handler = Kiri::getDi()->get($exceptionHandler);
|
||||
}
|
||||
return $this->handler->emit($exception, $response);
|
||||
}
|
||||
#[Inject(Logger::class)]
|
||||
public Logger $logger;
|
||||
|
||||
|
||||
/**
|
||||
@@ -58,7 +37,9 @@ class OnServerTask
|
||||
try {
|
||||
$data = $this->resolve($data);
|
||||
} catch (\Throwable $exception) {
|
||||
$data = $this->emit($exception, new Response());
|
||||
$data = jTraceEx($exception);
|
||||
|
||||
$this->logger->error('task', [$data]);
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
@@ -75,7 +56,9 @@ class OnServerTask
|
||||
try {
|
||||
$data = $this->resolve($task->data);
|
||||
} catch (\Throwable $exception) {
|
||||
$data = $this->emit($exception, new Response());
|
||||
$data = jTraceEx($exception);
|
||||
|
||||
$this->logger->error('task', [$data]);
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Worker;
|
||||
namespace Server\Handler;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server\Protocol;
|
||||
|
||||
|
||||
abstract class Protocol
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function resolveProtocol($data): array
|
||||
{
|
||||
$explode = explode("\r\n\r\n", $data);
|
||||
|
||||
$http_protocol = [];
|
||||
foreach (explode("\r\n", $explode[0]) as $key => $datum) {
|
||||
if (empty($datum) || $key == 0) {
|
||||
continue;
|
||||
}
|
||||
[$key, $value] = explode(': ', $datum);
|
||||
|
||||
$http_protocol[trim($key)] = trim($value);
|
||||
}
|
||||
return [$http_protocol, $explode[1]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Protocol;
|
||||
|
||||
|
||||
class WebSocket extends Protocol
|
||||
{
|
||||
|
||||
|
||||
//
|
||||
public function decode($received): ?string
|
||||
{
|
||||
$decoded = null;
|
||||
$buffer = $received;
|
||||
$len = ord($buffer[1]) & 127;
|
||||
if ($len === 126) {
|
||||
$masks = substr($buffer, 4, 4);
|
||||
$data = substr($buffer, 8);
|
||||
} else {
|
||||
if ($len === 127) {
|
||||
$masks = substr($buffer, 10, 4);
|
||||
$data = substr($buffer, 14);
|
||||
} else {
|
||||
$masks = substr($buffer, 2, 4);
|
||||
$data = substr($buffer, 6);
|
||||
}
|
||||
}
|
||||
for ($index = 0; $index < strlen($data); $index++) {
|
||||
$decoded .= $data[$index] ^ $masks[$index % 4];
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
const BINARY_TYPE_BLOB = "\x81";
|
||||
|
||||
|
||||
public function encode($buffer): string
|
||||
{
|
||||
$len = strlen($buffer);
|
||||
|
||||
$first_byte = self::BINARY_TYPE_BLOB;
|
||||
|
||||
if ($len <= 125) {
|
||||
$encode_buffer = $first_byte . chr($len) . $buffer;
|
||||
} else {
|
||||
if ($len <= 65535) {
|
||||
$encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;
|
||||
} else {
|
||||
//pack("xxxN", $len)pack函数只处理2的32次方大小的文件,实际上2的32次方已经4G了。
|
||||
$encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return $encode_buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return string
|
||||
*/
|
||||
private function getWebSocketProtocol($data): string
|
||||
{
|
||||
[$http_protocol, $body] = $this->resolveProtocol($data);
|
||||
$key = base64_encode(sha1($http_protocol['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
$headers = [
|
||||
'HTTP/1.1 101 Switching Protocols',
|
||||
'Upgrade: websocket',
|
||||
'Connection: Upgrade',
|
||||
'Sec-WebSocket-Accept: ' . $key,
|
||||
'Sec-WebSocket-Version: 13',
|
||||
];
|
||||
if (isset($http_protocol['Sec-WebSocket-Protocol'])) {
|
||||
$headers[] = 'Sec-WebSocket-Protocol: ' . $http_protocol['Sec-WebSocket-Protocol'];
|
||||
}
|
||||
return implode("\r\n", $headers) . "\r\n\r\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Server\Constrict\Response;
|
||||
use Http\Message\Stream;
|
||||
|
||||
class Sender
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var Response
|
||||
*/
|
||||
#[Inject(Response::class)]
|
||||
public Response $response;
|
||||
|
||||
|
||||
/**
|
||||
* @var ServerManager
|
||||
*/
|
||||
#[Inject(ServerManager::class)]
|
||||
public ServerManager $manager;
|
||||
|
||||
|
||||
/**
|
||||
* @param $fd
|
||||
* @param $data
|
||||
*/
|
||||
public function send($fd, $data)
|
||||
{
|
||||
$body = $this->response->withBody(new Stream($data));
|
||||
$server = $this->manager->getServer();
|
||||
if (!$server->isEstablished($fd)) {
|
||||
return;
|
||||
}
|
||||
$server->push($fd, $body->getBody()->getContents());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $fd
|
||||
* @param int $code
|
||||
* @param string $message
|
||||
*/
|
||||
public function close($fd, int $code = 401, string $message = '')
|
||||
{
|
||||
$server = $this->manager->getServer();
|
||||
if (!$server->isEstablished($fd)) {
|
||||
return;
|
||||
}
|
||||
$server->close($code, $message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ use Server\Abstracts\OnWorkerStart as WorkerDispatch;
|
||||
use Server\Events\OnBeforeWorkerStart;
|
||||
use Server\Events\OnTaskerStart;
|
||||
use Server\Events\OnWorkerStart;
|
||||
use Server\Worker\OnServerWorker;
|
||||
use Server\Handler\OnServerWorker;
|
||||
use Swoole\Coroutine;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
@@ -10,10 +10,14 @@ use Kiri\Di\ContainerInterface;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use ReflectionException;
|
||||
use Server\Manager\OnPipeMessage;
|
||||
use Server\Manager\OnServer;
|
||||
use Server\Manager\OnServerManager;
|
||||
use Server\Manager\OnServerReload;
|
||||
|
||||
use Server\Handler\OnPipeMessage;
|
||||
use Server\Handler\OnServer;
|
||||
use Server\Handler\OnServerManager;
|
||||
use Server\Handler\OnServerReload;
|
||||
use Server\Handler\OnServerWorker;
|
||||
use Server\Handler\OnServerTask;
|
||||
|
||||
use Server\SInterface\OnCloseInterface;
|
||||
use Server\SInterface\OnConnectInterface;
|
||||
use Server\SInterface\OnDisconnectInterface;
|
||||
@@ -23,8 +27,6 @@ use Server\SInterface\OnPacketInterface;
|
||||
use Server\SInterface\OnProcessInterface;
|
||||
use Server\SInterface\OnReceiveInterface;
|
||||
use Server\SInterface\OnTaskInterface;
|
||||
use Server\Task\OnServerTask;
|
||||
use Server\Worker\OnServerWorker;
|
||||
use Swoole\Http\Server as HServer;
|
||||
use Swoole\Process;
|
||||
use Swoole\Server;
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Service;
|
||||
|
||||
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
use Http\Handler\Abstracts\HandlerManager;
|
||||
use Http\Handler\Context;
|
||||
use Http\Handler\Dispatcher;
|
||||
use Http\Handler\Handler;
|
||||
use Http\Handler\Router;
|
||||
use Http\Message\ServerRequest;
|
||||
use Http\Message\Stream;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Server\Abstracts\Utility\EventDispatchHelper;
|
||||
use Server\Abstracts\Utility\ResponseHelper;
|
||||
use Server\Constrict\RequestInterface;
|
||||
use Server\Constrict\ResponseEmitter;
|
||||
use Server\Constrict\ResponseInterface;
|
||||
use Server\Events\OnAfterRequest;
|
||||
use Server\ExceptionHandlerDispatcher;
|
||||
use Server\ExceptionHandlerInterface;
|
||||
use Server\SInterface\OnCloseInterface;
|
||||
use Server\SInterface\OnConnectInterface;
|
||||
use Server\SInterface\OnRequestInterface;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Http implements OnCloseInterface, OnConnectInterface, OnRequestInterface
|
||||
{
|
||||
|
||||
use EventDispatchHelper;
|
||||
use ResponseHelper;
|
||||
|
||||
/** @var Router|mixed */
|
||||
#[Inject(Router::class)]
|
||||
public Router $router;
|
||||
|
||||
|
||||
/**
|
||||
* @var ExceptionHandlerInterface
|
||||
*/
|
||||
public ExceptionHandlerInterface $exceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$exceptionHandler = Config::get('exception.http', ExceptionHandlerDispatcher::class);
|
||||
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
|
||||
$exceptionHandler = ExceptionHandlerDispatcher::class;
|
||||
}
|
||||
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
|
||||
$this->responseEmitter = Kiri::getDi()->get(ResponseEmitter::class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onConnect(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement onConnect() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onRequest(Request $request, Response $response): void
|
||||
{
|
||||
try {
|
||||
[$PsrRequest, $PsrResponse] = $this->initRequestResponse($request);
|
||||
/** @var Handler $handler */
|
||||
$handler = HandlerManager::get($request->server['request_uri'], $request->getMethod());
|
||||
if (is_integer($handler)) {
|
||||
$PsrResponse->withStatus($handler)->withBody(new Stream('Allow Method[' . $request->getMethod() . '].'));
|
||||
} else if (is_null($handler)) {
|
||||
$PsrResponse->withStatus(404)->withBody(new Stream('Page not found.'));
|
||||
} else {
|
||||
$PsrResponse = $this->handler($handler, $PsrRequest);
|
||||
}
|
||||
} catch (\Throwable $throwable) {
|
||||
$PsrResponse = $this->exceptionHandler->emit($throwable, $this->response);
|
||||
} finally {
|
||||
$this->responseEmitter->sender($response, $PsrResponse);
|
||||
$this->eventDispatch->dispatch(new OnAfterRequest());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Handler $handler
|
||||
* @param $PsrRequest
|
||||
* @return ResponseInterface
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function handler(Handler $handler, $PsrRequest): \Psr\Http\Message\ResponseInterface
|
||||
{
|
||||
$dispatcher = new Dispatcher($handler, $handler->_middlewares);
|
||||
return $dispatcher->handle($PsrRequest);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array<ServerRequestInterface, ResponseInterface>
|
||||
* @throws Exception
|
||||
*/
|
||||
private function initRequestResponse(Request $request): array
|
||||
{
|
||||
$PsrResponse = Context::setContext(ResponseInterface::class, new \Http\Message\Response());
|
||||
|
||||
$PsrRequest = Context::setContext(RequestInterface::class, ServerRequest::createServerRequest($request));
|
||||
if ($PsrRequest->isMethod('OPTIONS')) {
|
||||
$request->server['request_uri'] = '/*';
|
||||
}
|
||||
return [$PsrRequest, $PsrResponse];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onDisconnect(Server $server, int $fd): void
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onClose(Server $server, int $fd): void
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Service;
|
||||
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Server\Abstracts\Utility\EventDispatchHelper;
|
||||
use Server\Abstracts\Utility\ResponseHelper;
|
||||
use Server\Constrict\TcpEmitter;
|
||||
use Server\ExceptionHandlerDispatcher;
|
||||
use Server\ExceptionHandlerInterface;
|
||||
use Server\SInterface\OnCloseInterface;
|
||||
use Server\SInterface\OnConnectInterface;
|
||||
use Server\SInterface\OnReceiveInterface;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Tcp implements OnConnectInterface, OnCloseInterface, OnReceiveInterface
|
||||
{
|
||||
|
||||
use EventDispatchHelper;
|
||||
use ResponseHelper;
|
||||
|
||||
|
||||
/**
|
||||
* @var ExceptionHandlerInterface
|
||||
*/
|
||||
public ExceptionHandlerInterface $exceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$exceptionHandler = Config::get('exception.tcp', ExceptionHandlerDispatcher::class);
|
||||
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
|
||||
$exceptionHandler = ExceptionHandlerDispatcher::class;
|
||||
}
|
||||
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
|
||||
$this->responseEmitter = Kiri::getDi()->get(TcpEmitter::class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onConnect(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement onConnect() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
* @param int $reactor_id
|
||||
* @param string $data
|
||||
*/
|
||||
public function onReceive(Server $server, int $fd, int $reactor_id, string $data): void
|
||||
{
|
||||
// TODO: Implement onReceive() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onClose(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement onClose() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onDisconnect(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement onDisconnect() method.
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Service;
|
||||
|
||||
|
||||
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Server\Abstracts\Server;
|
||||
use Server\Abstracts\Utility\EventDispatchHelper;
|
||||
use Server\Abstracts\Utility\ResponseHelper;
|
||||
use Server\Constrict\UdpEmitter;
|
||||
use Server\ExceptionHandlerDispatcher;
|
||||
use Server\ExceptionHandlerInterface;
|
||||
use Server\SInterface\OnPacketInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Udp implements OnPacketInterface
|
||||
{
|
||||
|
||||
use EventDispatchHelper;
|
||||
use ResponseHelper;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @var ExceptionHandlerInterface
|
||||
*/
|
||||
public ExceptionHandlerInterface $exceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$exceptionHandler = Config::get('exception.udp', ExceptionHandlerDispatcher::class);
|
||||
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
|
||||
$exceptionHandler = ExceptionHandlerDispatcher::class;
|
||||
}
|
||||
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
|
||||
$this->responseEmitter = Kiri::getDi()->get(UdpEmitter::class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $data
|
||||
* @param array $clientInfo
|
||||
*/
|
||||
public function onPacket(Server $server, string $data, array $clientInfo): void
|
||||
{
|
||||
// TODO: Implement onPacket() method.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Service;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Config;
|
||||
use Kiri\Exception\ConfigException;
|
||||
use Kiri\Kiri;
|
||||
use Server\Abstracts\Utility\EventDispatchHelper;
|
||||
use Server\Abstracts\Utility\ResponseHelper;
|
||||
use Server\Constrict\WebSocketEmitter;
|
||||
use Server\ExceptionHandlerDispatcher;
|
||||
use Server\ExceptionHandlerInterface;
|
||||
use Server\SInterface\OnCloseInterface;
|
||||
use Server\SInterface\OnHandshakeInterface;
|
||||
use Server\SInterface\OnMessageInterface;
|
||||
use Server\SInterface\OnRequestInterface;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
use Swoole\WebSocket\Frame;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class WebSocket implements OnHandshakeInterface, OnMessageInterface, OnCloseInterface
|
||||
{
|
||||
|
||||
|
||||
use EventDispatchHelper;
|
||||
use ResponseHelper;
|
||||
|
||||
|
||||
/**
|
||||
* @var ExceptionHandlerInterface
|
||||
*/
|
||||
public ExceptionHandlerInterface $exceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$exceptionHandler = Config::get('exception.websocket', ExceptionHandlerDispatcher::class);
|
||||
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
|
||||
$exceptionHandler = ExceptionHandlerDispatcher::class;
|
||||
}
|
||||
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
|
||||
$this->responseEmitter = Kiri::getDi()->get(WebSocketEmitter::class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onHandshake(Request $request, Response $response): void
|
||||
{
|
||||
// TODO: Implement OnHandshakeInterface() method.
|
||||
$secWebSocketKey = $request->header['sec-websocket-key'];
|
||||
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
|
||||
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
|
||||
throw new Exception('protocol error.', 500);
|
||||
}
|
||||
$key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
$headers = [
|
||||
'Upgrade' => 'websocket',
|
||||
'Connection' => 'Upgrade',
|
||||
'Sec-websocket-Accept' => $key,
|
||||
'Sec-websocket-Version' => '13',
|
||||
];
|
||||
if (isset($request->header['sec-websocket-protocol'])) {
|
||||
$explode = explode(',',$request->header['sec-websocket-protocol']);
|
||||
$headers['Sec-websocket-Protocol'] = $explode[0];
|
||||
}
|
||||
foreach ($headers as $key => $val) {
|
||||
$response->setHeader($key, $val);
|
||||
}
|
||||
$response->status(101);
|
||||
$response->end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function onMessage(Server $server, Frame $frame): void
|
||||
{
|
||||
// TODO: Implement OnMessageInterface() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onClose(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement OnCloseInterface() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onDisconnect(Server $server, int $fd): void
|
||||
{
|
||||
// TODO: Implement OnDisconnectInterface() method.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user