Merge branch 'master' of https://gitee.com/dreamwithouttrace/kiri-core
This commit is contained in:
+12
-1
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Kiri\Jwt;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
use Kiri\Abstracts\Component;
|
||||
use Kiri\Abstracts\Config;
|
||||
@@ -21,9 +22,19 @@ class Jwt extends Component
|
||||
use JwtHelper;
|
||||
|
||||
|
||||
#[Inject(Request::class)]
|
||||
private Request $request;
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
public function setRequest(Request $request): void
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
@@ -96,7 +107,7 @@ class Jwt extends Component
|
||||
*/
|
||||
private function jwtBody($unionId): string
|
||||
{
|
||||
$json = json_encode(['unionId' => $unionId, 'createTime' => time(), 'loginIp' => request()->getIp(), 'expire_at' => time() + $this->timeout]);
|
||||
$json = json_encode(['unionId' => $unionId, 'createTime' => time(), 'expire_at' => time() + $this->timeout]);
|
||||
openssl_private_encrypt($json, $encode, $this->private);
|
||||
return base64_encode($encode);
|
||||
}
|
||||
|
||||
@@ -710,19 +710,6 @@ if (!function_exists('request')) {
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('Input')) {
|
||||
|
||||
/**
|
||||
* @return HttpParams
|
||||
* @throws Exception
|
||||
*/
|
||||
function Input(): HttpParams
|
||||
{
|
||||
return request()->params;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!function_exists('storage')) {
|
||||
|
||||
/**
|
||||
@@ -771,20 +758,6 @@ if (!function_exists('event')) {
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('alias')) {
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @param $name
|
||||
*/
|
||||
function alias($class, $name)
|
||||
{
|
||||
Kiri::setAlias($class, $name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!function_exists('name')) {
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,10 @@ trait HttpHeaders
|
||||
private array $_headers = [];
|
||||
|
||||
|
||||
|
||||
private array $_server = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,10 @@ trait HttpParams
|
||||
private ?array $_files = [];
|
||||
|
||||
|
||||
/** @var string */
|
||||
private string $_body = '';
|
||||
|
||||
|
||||
private mixed $_rawContent = '';
|
||||
|
||||
/**
|
||||
@@ -63,26 +67,36 @@ trait HttpParams
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|string $rawContent
|
||||
* @param \Swoole\Http\Request $request
|
||||
*/
|
||||
public function setRawContent(mixed $rawContent, string $context_type): void
|
||||
public function setParseBody(\Swoole\Http\Request $request): void
|
||||
{
|
||||
if (str_contains($context_type, 'json')) {
|
||||
$this->_rawContent = json_decode($rawContent, true);
|
||||
} else if (str_contains($context_type, 'xml')) {
|
||||
$this->_rawContent = Xml::toArray($rawContent);
|
||||
$content = $request->getContent();
|
||||
if (empty($content)) {
|
||||
return;
|
||||
}
|
||||
$contentType = $request->header['content-type'];
|
||||
if (str_contains($contentType, 'json')) {
|
||||
$this->_posts = json_decode($contentType, true);
|
||||
} else if (str_contains($contentType, 'xml')) {
|
||||
$this->_posts = Xml::toArray($contentType);
|
||||
} else if (str_contains($contentType, 'x-www-form-urlencoded')) {
|
||||
$this->_posts = $request->post;
|
||||
} else if (str_contains($contentType, 'serialize')) {
|
||||
$this->_posts = unserialize($content);
|
||||
} else {
|
||||
$this->_rawContent = $rawContent;
|
||||
$this->_body = $content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRawContent(): mixed
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->_rawContent;
|
||||
return $this->_body;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -181,9 +181,10 @@ class Request extends HttpService implements RequestInterface
|
||||
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param AuthIdentity $value
|
||||
* @return AuthIdentity
|
||||
*/
|
||||
public function setGrantAuthorization($value)
|
||||
public function setGrantAuthorization(AuthIdentity $value): AuthIdentity
|
||||
{
|
||||
return $this->_grant = $value;
|
||||
}
|
||||
@@ -231,7 +232,6 @@ class Request extends HttpService implements RequestInterface
|
||||
if (!empty($this->_platform)) {
|
||||
return $this->_platform;
|
||||
}
|
||||
|
||||
$user = $this->getAgent();
|
||||
$match = preg_match('/\(.*\)?/', $user, $output);
|
||||
if (!$match || count($output) < 1) {
|
||||
@@ -346,23 +346,6 @@ class Request extends HttpService implements RequestInterface
|
||||
return $this->isCli === TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$method = 'set' . ucfirst($name);
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($value);
|
||||
} else {
|
||||
parent::__set($name, $value); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
|
||||
@@ -7,12 +7,9 @@ namespace Http\Route;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Http\Context\Context;
|
||||
use Http\Context\Request;
|
||||
use Http\Context\Response;
|
||||
use Http\IInterface\MiddlewareInterface;
|
||||
use Server\RequestInterface;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class CoreMiddleware
|
||||
@@ -26,7 +23,7 @@ class CoreMiddleware extends MiddlewareAbstracts
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param RequestInterface $request
|
||||
* @param Closure $next
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
@@ -36,8 +33,8 @@ class CoreMiddleware extends MiddlewareAbstracts
|
||||
/** @var Response $response */
|
||||
$response = \response();
|
||||
$response->addHeader('Access-Control-Allow-Origin', '*');
|
||||
$response->addHeader('Access-Control-Allow-Headers', $request->header('access-control-request-headers'));
|
||||
$response->addHeader('Access-Control-Request-Method', $request->header('access-control-request-method'));
|
||||
$response->addHeader('Access-Control-Allow-Headers', $request->getHeaderLine('Access-Control-Request-Headers'));
|
||||
$response->addHeader('Access-Control-Request-Method', $request->getHeaderLine('Access-Control-Request-Method'));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ class Node
|
||||
public function checkSuffix(): bool
|
||||
{
|
||||
if ($this->enableHtmlSuffix) {
|
||||
$url = request()->getUri();
|
||||
$url = request()->getUri()->getPath();
|
||||
$nowLength = strlen($this->htmlSuffix);
|
||||
if (strpos($url, $this->htmlSuffix) !== strlen($url) - $nowLength) {
|
||||
return false;
|
||||
|
||||
@@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Http\Route;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
@@ -46,6 +47,13 @@ class Router extends HttpService implements RouterInterface
|
||||
public ?Response $response = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var RequestInterface
|
||||
*/
|
||||
#[Inject(RequestInterface::class)]
|
||||
public RequestInterface $request;
|
||||
|
||||
|
||||
/**
|
||||
* @param Closure $middleware
|
||||
*/
|
||||
@@ -495,7 +503,7 @@ class Router extends HttpService implements RouterInterface
|
||||
{
|
||||
$method = $request->getMethod();
|
||||
|
||||
$methods = $this->nodes[$method][\request()->getUri()] ?? null;
|
||||
$methods = $this->nodes[$method][\request()->getUri()->getPath()] ?? null;
|
||||
if (!is_null($methods)) {
|
||||
return $methods;
|
||||
}
|
||||
@@ -548,11 +556,12 @@ class Router extends HttpService implements RouterInterface
|
||||
*/
|
||||
public function Branch_search(RequestInterface $request): ?Node
|
||||
{
|
||||
$node = $this->tree_search($request->getExplode(), $request->getMethod());
|
||||
$uri = $request->getUri();
|
||||
$node = $this->tree_search($uri->getExplode(), $request->getMethod());
|
||||
if ($node instanceof Node) {
|
||||
return $node;
|
||||
}
|
||||
if (!$request->isOption) {
|
||||
if (!$request->isMethod('OPTIONS')) {
|
||||
return null;
|
||||
}
|
||||
$node = $this->tree_search(['*'], $request->getMethod());
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Server\Constrict;
|
||||
|
||||
use Http\Context\Context;
|
||||
use Http\Context\Request as HttpResponse;
|
||||
use Server\Message\Request as RequestMessage;
|
||||
use Http\Context\Response;
|
||||
use Kiri\Kiri;
|
||||
use ReflectionException;
|
||||
@@ -11,7 +11,7 @@ use Server\RequestInterface;
|
||||
|
||||
|
||||
/**
|
||||
* @mixin HttpResponse
|
||||
* @mixin RequestMessage
|
||||
*/
|
||||
class Request implements RequestInterface
|
||||
{
|
||||
@@ -24,10 +24,10 @@ class Request implements RequestInterface
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
{
|
||||
if (!Context::hasContext(HttpResponse::class)) {
|
||||
$request = Context::setContext(HttpResponse::class, new HttpResponse());
|
||||
if (!Context::hasContext(RequestMessage::class)) {
|
||||
$request = Context::setContext(RequestMessage::class, new RequestMessage());
|
||||
} else {
|
||||
$request = Context::getContext(HttpResponse::class);
|
||||
$request = Context::getContext(RequestMessage::class);
|
||||
}
|
||||
if (property_exists($request, $name)) {
|
||||
return $request->{$name};
|
||||
@@ -43,7 +43,7 @@ class Request implements RequestInterface
|
||||
public function __get($name): mixed
|
||||
{
|
||||
// TODO: Change the autogenerated stub
|
||||
return Context::getContext(HttpResponse::class)->{$name};
|
||||
return Context::getContext(RequestMessage::class)->{$name};
|
||||
}
|
||||
|
||||
|
||||
@@ -56,21 +56,7 @@ class Request implements RequestInterface
|
||||
{
|
||||
Context::setContext(Response::class, new Response());
|
||||
|
||||
$sRequest = new HttpResponse();
|
||||
|
||||
var_dump($request->getData(), $request->header);
|
||||
|
||||
$sRequest->setHeaders(array_merge($request->header, $request->server));
|
||||
|
||||
$sRequest->setUri($sRequest->getRequestUri());
|
||||
$sRequest->setClientId($request->fd);
|
||||
|
||||
$sRequest->setRawContent($request->rawContent(), $sRequest->getContentType());
|
||||
$sRequest->setFiles($request->files ?? []);
|
||||
$sRequest->setPosts($request->post ?? []);
|
||||
$sRequest->setGets($request->get ?? []);
|
||||
|
||||
Context::setContext(HttpResponse::class, $sRequest);
|
||||
Context::setContext(RequestMessage::class, RequestMessage::parseRequest($request));
|
||||
|
||||
return Kiri::getDi()->get(Request::class);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
class Headers
|
||||
{
|
||||
|
||||
|
||||
private array $headers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
* @return $this
|
||||
*/
|
||||
public function withHeader(array $headers): static
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->headers = $headers;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return string|array|float|int|null
|
||||
*/
|
||||
public function get($name, $default = null): string|array|float|int|null
|
||||
{
|
||||
return $this->headers[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Kiri\Core\Xml;
|
||||
use Kiri\Kiri;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use ReflectionException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
trait Message
|
||||
{
|
||||
|
||||
public string $version;
|
||||
|
||||
|
||||
public StreamInterface $stream;
|
||||
|
||||
|
||||
public array $headers = [];
|
||||
|
||||
|
||||
public array $servers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocolVersion(): string
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $version
|
||||
* @return $this
|
||||
*/
|
||||
public function withProtocolVersion($version): static
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->version = $version;
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $request
|
||||
* @return $this
|
||||
*/
|
||||
private function parseRequestHeaders(\Swoole\Http\Request $request): static
|
||||
{
|
||||
$index = strpos($request->getData(), "\r\n\r\n");
|
||||
$headers = explode("\r\n", substr($request->getData(), 0, $index));
|
||||
|
||||
array_shift($headers);
|
||||
foreach ($headers as $header) {
|
||||
[$key, $value] = explode(': ', $header);
|
||||
$this->addRequestHeader($key, $value);
|
||||
}
|
||||
// $class = Kiri::getDi()->get(Headers::class);
|
||||
// $this->header = $class->withHeader($this->headers);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $value
|
||||
*/
|
||||
private function addRequestHeader($key, $value)
|
||||
{
|
||||
$this->headers[$key] = [];
|
||||
foreach (explode(';', $value) as $item) {
|
||||
$this->headers[$key][] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return string|null
|
||||
*/
|
||||
#[Pure] public function getHeaderLine($name): string|null
|
||||
{
|
||||
if ($this->hasHeader($name)) {
|
||||
return implode(';', $this->headers[$name]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
*/
|
||||
public function withHeader($name, $value): static
|
||||
{
|
||||
$class = clone $this;
|
||||
if (!is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
$class->headers[$name] = $value;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
* @throws
|
||||
*/
|
||||
public function withAddedHeader($name, $value): static
|
||||
{
|
||||
$class = clone $this;
|
||||
if (!array_key_exists($name, $class->headers)) {
|
||||
throw new \Exception('Headers `' . $name . '` not exists.');
|
||||
}
|
||||
$class->headers[$name][] = $value;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return $this
|
||||
*/
|
||||
public function withoutHeader($name): static
|
||||
{
|
||||
$class = clone $this;
|
||||
unset($class->headers[$name]);
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBody(): string
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param StreamInterface $body
|
||||
* @return static
|
||||
*/
|
||||
public function withBody(StreamInterface $body): static
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->stream = $body;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param StreamInterface $stream
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseBody(StreamInterface $stream): mixed
|
||||
{
|
||||
$content = $stream->getContents();
|
||||
if (empty($content)) {
|
||||
return $content;
|
||||
}
|
||||
$contentType = $this->getHeaderLine('content-type');
|
||||
if (str_contains($contentType, 'json')) {
|
||||
return json_encode($contentType);
|
||||
}
|
||||
if (str_contains($contentType, 'xml')) {
|
||||
return Xml::toArray($contentType);
|
||||
}
|
||||
if (str_contains($contentType, 'x-www-form-urlencoded')) {
|
||||
parse_str($content, $array);
|
||||
return $array;
|
||||
}
|
||||
if (str_contains($contentType, 'serialize')) {
|
||||
return unserialize($content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use Annotation\Inject;
|
||||
use BadMethodCallException;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use ReflectionException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Request implements RequestInterface
|
||||
{
|
||||
|
||||
use Message;
|
||||
|
||||
|
||||
public string $requestTarget;
|
||||
|
||||
|
||||
public string $method;
|
||||
|
||||
|
||||
/**
|
||||
* @var Uri
|
||||
*/
|
||||
private Uri $uri;
|
||||
|
||||
|
||||
private \Swoole\Http\Request $serverRequest;
|
||||
|
||||
|
||||
private array $parseBody;
|
||||
|
||||
private array $files = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int
|
||||
{
|
||||
return $this->serverRequest->fd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $request
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public static function parseRequest(\Swoole\Http\Request $request): RequestInterface
|
||||
{
|
||||
$message = new Request();
|
||||
$message->uri = Uri::parseUri($request);
|
||||
$message->method = $request->getMethod();
|
||||
$message->requestTarget = '';
|
||||
$message->serverRequest = $request;
|
||||
$message->version = $request->server['server_protocol'];
|
||||
$message->stream = new Stream($request->getContent());
|
||||
$message->servers = $request->server;
|
||||
$message->parseRequestHeaders($request);
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
#[Pure] public function getStartTime(): float
|
||||
{
|
||||
return $this->servers['request_time_float'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function input($name, $default = null): mixed
|
||||
{
|
||||
if (empty($this->parseBody)) {
|
||||
$this->parseBody = $this->parseBody($this->stream);
|
||||
}
|
||||
if (!is_array($this->parseBody)) {
|
||||
return $default;
|
||||
}
|
||||
return $this->parseBody[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($name, $default = null): mixed
|
||||
{
|
||||
return $this->serverRequest->post[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($name, $default = null): mixed
|
||||
{
|
||||
return $this->serverRequest->get[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return Uploaded|null
|
||||
*/
|
||||
public function file($name): ?Uploaded
|
||||
{
|
||||
if (isset($this->serverRequest->files[$name])) {
|
||||
return new Uploaded($this->serverRequest->files[$name]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestTarget(): string
|
||||
{
|
||||
throw new BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $requestTarget
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function withRequestTarget($requestTarget): RequestInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->requestTarget = $requestTarget;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod(): string
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function isMethod(string $method): bool
|
||||
{
|
||||
return $this->method === $method;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function withMethod($method): RequestInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->method = $method;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function getUri(): UriInterface
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param UriInterface $uri
|
||||
* @param false $preserveHost
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->uri = $uri;
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Response implements ResponseInterface
|
||||
{
|
||||
use Message;
|
||||
|
||||
public int $statusCode = 200;
|
||||
|
||||
|
||||
public string $reasonPhrase = '';
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatusCode(): int
|
||||
{
|
||||
// TODO: Implement getStatusCode() method.
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
* @param string $reasonPhrase
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function withStatus($code, $reasonPhrase = ''): ResponseInterface
|
||||
{
|
||||
// TODO: Implement withStatus() method.
|
||||
$class = clone $this;
|
||||
$class->statusCode = $code;
|
||||
$class->reasonPhrase = $reasonPhrase;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getReasonPhrase(): string
|
||||
{
|
||||
// TODO: Implement getReasonPhrase() method.
|
||||
return $this->reasonPhrase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Stream implements StreamInterface
|
||||
{
|
||||
|
||||
|
||||
private string $body;
|
||||
|
||||
|
||||
private int $size;
|
||||
|
||||
|
||||
private int $offset = 0;
|
||||
|
||||
|
||||
private bool $writable = true;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $body
|
||||
*/
|
||||
public function __construct(string $body)
|
||||
{
|
||||
$this->body = $body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
$this->detach();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function detach(): void
|
||||
{
|
||||
$this->body = '';
|
||||
$this->size = 0;
|
||||
$this->writable = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSize(): int
|
||||
{
|
||||
if ($this->size == 0) {
|
||||
$this->size = strlen($this->body);
|
||||
}
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function tell(): int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function eof(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSeekable(): bool
|
||||
{
|
||||
return $this->offset == 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $whence
|
||||
*/
|
||||
public function seek($offset, $whence = SEEK_SET)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable(): bool
|
||||
{
|
||||
return $this->writable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
public function write($string): int
|
||||
{
|
||||
// TODO: Implement write() method.
|
||||
$this->body .= $string;
|
||||
$this->size = strlen($this->body);
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public function read($length): string
|
||||
{
|
||||
// TODO: Implement read() method.
|
||||
return substr($this->body, 0, $length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContents(): string
|
||||
{
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param null $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMetadata($key = null): mixed
|
||||
{
|
||||
throw new \BadMethodCallException('Not Accomplish Method.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Uploaded implements UploadedFileInterface
|
||||
{
|
||||
|
||||
public string $tmp_name;
|
||||
|
||||
|
||||
public string $name;
|
||||
|
||||
|
||||
public string $type;
|
||||
|
||||
|
||||
public string $size;
|
||||
|
||||
|
||||
public int $error;
|
||||
|
||||
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"
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $file
|
||||
*/
|
||||
public function __construct(array $file)
|
||||
{
|
||||
$this->tmp_name = $file['tmp_name'];
|
||||
$this->name = $file['name'];
|
||||
$this->type = $file['type'];
|
||||
$this->size = $file['size'];
|
||||
$this->error = $file['error'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return StreamInterface
|
||||
*/
|
||||
public function getStream(): StreamInterface
|
||||
{
|
||||
return new Stream(file_get_contents($this->tmp_name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $targetPath
|
||||
*/
|
||||
public function moveTo($targetPath)
|
||||
{
|
||||
@move_uploaded_file($this->tmp_name, $targetPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSize(): int
|
||||
{
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getError(): string
|
||||
{
|
||||
return Uploaded::ERROR[$this->error] ?? 'unknown error';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getClientFilename(): string|null
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getClientMediaType(): string|null
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Message;
|
||||
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
|
||||
class Uri implements UriInterface
|
||||
{
|
||||
|
||||
|
||||
public string $scheme = '';
|
||||
|
||||
|
||||
public string $host = '';
|
||||
|
||||
public int $port = 80;
|
||||
|
||||
|
||||
public string $path = '';
|
||||
|
||||
|
||||
public string $query = '';
|
||||
|
||||
|
||||
public string $fragment = '';
|
||||
|
||||
|
||||
public string $username = '';
|
||||
|
||||
|
||||
public string $password = '';
|
||||
|
||||
|
||||
private array $_explode = [];
|
||||
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExplode(): array
|
||||
{
|
||||
if ($this->path == '/' || $this->path == '') {
|
||||
return [''];
|
||||
}
|
||||
if (empty($this->_explode)) {
|
||||
$this->_explode = array_filter(explode('/', $this->path));
|
||||
}
|
||||
return $this->_explode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme(): string
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
public function getAuthority()
|
||||
{
|
||||
// TODO: Implement getAuthority() method.
|
||||
}
|
||||
|
||||
public function getUserInfo()
|
||||
{
|
||||
// TODO: Implement getUserInfo() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPort(): int
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPath(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQuery(): string
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFragment(): string
|
||||
{
|
||||
return $this->fragment;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withScheme($scheme): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->scheme = $scheme;
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param null $password
|
||||
* @return $this
|
||||
*/
|
||||
public function withUserInfo($user, $password = null): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->username = $user;
|
||||
$class->password = $password;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $host
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withHost($host): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->host = $host;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDefaultPort(): int
|
||||
{
|
||||
return 80;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int|null $port
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withPort($port): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->port = $port;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withPath($path): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->path = $path;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withQuery($query): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->query = $query;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $fragment
|
||||
* @return UriInterface
|
||||
*/
|
||||
public function withFragment($fragment): UriInterface
|
||||
{
|
||||
$class = clone $this;
|
||||
$class->fragment = $fragment;
|
||||
return $class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return sprintf('%s://%s:%d%s?%s#%s', $this->scheme, $this->host, $this->port,
|
||||
$this->path, $this->query, $this->fragment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\Http\Request $request
|
||||
* @return UriInterface
|
||||
*/
|
||||
#[Pure] public static function parseUri(\Swoole\Http\Request $request): UriInterface
|
||||
{
|
||||
$server = $request->server;
|
||||
$header = $request->header;
|
||||
$uri = new Uri();
|
||||
$uri = $uri->withScheme(!empty($server['https']) && $server['https'] !== 'off' ? 'https' : 'http');
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
namespace Server;
|
||||
|
||||
|
||||
use Http\Context\Request;
|
||||
|
||||
use Server\Message\Request;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user