This commit is contained in:
2021-10-25 18:25:14 +08:00
parent 6605aae410
commit a9d106a1cf
48 changed files with 5090 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace Http\Constrict;
interface Emitter
{
/**
* @param mixed $response
* @param ResponseInterface $emitter
* @return mixed
*/
public function sender(mixed $response, ResponseInterface $emitter): void;
}
+509
View File
@@ -0,0 +1,509 @@
<?php
namespace Http\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__}();
}
}
+155
View File
@@ -0,0 +1,155 @@
<?php
namespace Http\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;
}
+361
View File
@@ -0,0 +1,361 @@
<?php
namespace Http\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 Http\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');
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace Http\Constrict;
use Annotation\Inject;
use Http\OnDownloadInterface;
/**
*
*/
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);
}
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
namespace Http\Constrict;
use JetBrains\PhpStorm\Pure;
use Http\Message\Response;
use Http\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;
}