This commit is contained in:
as2252258@163.com
2021-09-12 03:46:24 +08:00
parent 989158bc3d
commit b91199671a
8 changed files with 1151 additions and 1090 deletions
+2 -3
View File
@@ -70,8 +70,7 @@ class Node
/** /**
* @throws NotFindClassException * @param \Http\Route\Router $router
* @throws ReflectionException
*/ */
public function __construct(public Router $router) public function __construct(public Router $router)
{ {
@@ -197,7 +196,7 @@ class Node
* @param RequestInterface $request * @param RequestInterface $request
* @return bool * @return bool
*/ */
#[Pure] public function methodAllow(RequestInterface $request): bool public function methodAllow(RequestInterface $request): bool
{ {
if (!in_array($request->getMethod(), $this->method)) { if (!in_array($request->getMethod(), $this->method)) {
return true; return true;
+52 -41
View File
@@ -15,6 +15,7 @@ use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException; use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException; use Kiri\Exception\NotFindClassException;
use Kiri\Kiri; use Kiri\Kiri;
use Psr\Http\Message\UriInterface;
use ReflectionException; use ReflectionException;
use Server\Constrict\RequestInterface; use Server\Constrict\RequestInterface;
use Throwable; use Throwable;
@@ -28,7 +29,7 @@ defined('ROUTER_HASH') or define('ROUTER_HASH', 2);
*/ */
class Router extends HttpService implements RouterInterface class Router extends HttpService implements RouterInterface
{ {
/** @var Node[] $nodes */ /** @var \Http\Route\Node[] $nodes */
public array $nodes = []; public array $nodes = [];
public array $groupTacks = []; public array $groupTacks = [];
public ?string $namespace = 'App\\Http\\Controllers'; public ?string $namespace = 'App\\Http\\Controllers';
@@ -133,15 +134,12 @@ class Router extends HttpService implements RouterInterface
*/ */
private function tree($path, $handler, string $method = 'any'): Node private function tree($path, $handler, string $method = 'any'): Node
{ {
$explode = $this->split($path); [$parent, $explode] = $this->getRootNode($path, $method);
$start = array_shift($explode);
$parent = $this->nodes[$start] ?? null;
if (is_null($parent)) {
$parent = $this->nodes[$start] = $this->NodeInstance($start, 0, $method);
}
if (!empty($explode)) { if (!empty($explode)) {
$parent = $this->bindNode($parent, $explode, $method); $parent = $this->bindNode($parent, $explode, $method);
} }
if (!in_array($method, $parent->method)) { if (!in_array($method, $parent->method)) {
$parent->method[] = $method; $parent->method[] = $method;
} }
@@ -149,6 +147,31 @@ class Router extends HttpService implements RouterInterface
} }
/**
* @param $root
* @param $method
* @param bool $create
* @return array<\Http\Route\Node, array>
*/
private function getRootNode($root, $method, bool $create = true): array
{
[$start, $explode] = $this->path_recombination($root);
foreach ($this->nodes as $node) {
if ($node->path == $start) {
return [$node, $explode];
}
}
if ($create) {
$parent = $this->NodeInstance($root, 0, $method);
$this->nodes[] = $parent;
return [$parent, $explode];
}
return [null, null];
}
/** /**
* @param Node $parent * @param Node $parent
* @param array $explode * @param array $explode
@@ -401,8 +424,13 @@ class Router extends HttpService implements RouterInterface
*/ */
public function tree_search(?array $explode): ?Node public function tree_search(?array $explode): ?Node
{ {
$parent = $this->nodes[array_shift($explode)] ?? null; $start = array_shift($explode);
if (is_null($parent)) { foreach ($this->nodes as $node) {
if ($node->path == $start) {
$parent = $node;
}
}
if (!isset($parent)) {
return null; return null;
} }
while ($value = array_shift($explode)) { while ($value = array_shift($explode)) {
@@ -419,17 +447,17 @@ class Router extends HttpService implements RouterInterface
* @param $path * @param $path
* @return array|null * @return array|null
*/ */
public function split($path): ?array public function path_recombination($path): ?array
{ {
$path = $this->addPrefix() . '/' . ltrim($path, '/'); $path = $this->addPrefix() . '/' . ltrim($path, '/');
if ($path === '/') { if ($path === '/') {
return ['/']; return ['/', null];
} }
$filter = array_filter(explode('/', $path)); $filter = array_filter(explode('/', $path));
if (!empty($filter)) { if (!empty($filter)) {
return $filter; return [array_shift($filter), $filter];
} }
return ['/']; return ['/', null];
} }
/** /**
@@ -475,44 +503,27 @@ class Router extends HttpService implements RouterInterface
} }
/**
* @param $uri
* @param $method
* @return Node|null
*/
public function search($uri, $method): Node|null
{
if (!isset($this->nodes[$method])) {
return null;
}
$methods = $this->nodes[$method];
if (isset($methods[$uri])) {
return $methods[$uri];
}
return $methods['/'] ?? null;
}
/** /**
* @param RequestInterface $request * @param RequestInterface $request
* @return Node|null * @return Node|null
* 树杈搜索 * 树杈搜索
* @throws Exception * @throws Exception
*/ */
public function Branch_search(RequestInterface $request): ?Node public function radix_tree(RequestInterface $request): ?Node
{ {
$uri = $request->getUri(); [$parent, $explode] = $this->getRootNode($request->getUri()->getPath(),
if ($request->isMethod('OPTIONS')) { $request->getMethod(), false);
$node = $this->tree_search(['*']); if ($parent && !empty($explode)) {
/** @var \Http\Route\Node $parent */
foreach ($explode as $value) {
$node = $parent->findNode($value);
if (!$node) {
return null;
} }
if (!isset($node)) { $parent = $node;
$_explode = array_filter(explode('/', $uri->getPath()));
if (empty($_explode)) {
$_explode = ['/'];
} }
$node = $this->tree_search($_explode);
} }
return $node; return $parent;
} }
+56 -9
View File
@@ -3,7 +3,7 @@
namespace Protocol\Message; namespace Protocol\Message;
use JetBrains\PhpStorm\Pure; use JetBrains\PhpStorm\Pure;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@@ -31,7 +31,6 @@ trait Message
protected array $headers = []; protected array $headers = [];
/** /**
* @var array|null * @var array|null
*/ */
@@ -90,22 +89,64 @@ trait Message
/** /**
* @param \Swoole\Http\Request $request * @return array
* @return static
*/ */
public function parseRequestHeaders(\Swoole\Http\Request $request): static public function parse_curl_header(): array
{ {
$index = strpos($request->getData(), "\r\n\r\n"); $_headers = [];
$headers = explode("\r\n", substr($request->getData(), 0, $index)); foreach ($this->headers as $key => $val) {
array_shift($headers); $_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) { foreach ($headers as $header) {
[$key, $value] = explode(': ', $header); [$key, $value] = explode(': ', $header);
$this->addRequestHeader($key, $value); $this->withHeader($key, $value);
} }
return $this; 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 $key
* @param $value * @param $value
@@ -245,4 +286,10 @@ trait Message
return $this->getHeaderLine('Access-Control-Request-Method'); return $this->getHeaderLine('Access-Control-Request-Method');
} }
protected function setStore($key, callable $callback)
{
}
} }
+1 -1
View File
@@ -11,7 +11,7 @@ use Psr\Http\Message\UriInterface;
/** /**
* *
*/ */
abstract class Request implements RequestInterface class Request implements RequestInterface
{ {
use Message; use Message;
+24 -22
View File
@@ -14,6 +14,9 @@ class ServerRequest extends Request implements ServerRequestInterface
{ {
const PARSE_BODY = 'with.parsed.body.callback';
/** /**
* @var mixed * @var mixed
*/ */
@@ -64,29 +67,21 @@ class ServerRequest extends Request implements ServerRequestInterface
/** /**
* @param \Swoole\Http\Request $request * @param \Swoole\Http\Request $request
* @return static|ServerRequestInterface * @return static|ServerRequestInterface
* @throws \Exception
*/ */
public static function createServerRequest(\Swoole\Http\Request $request): static|ServerRequestInterface public static function createServerRequest(\Swoole\Http\Request $request): static|ServerRequestInterface
{ {
return (new static())->parseRequestHeaders($request) $serverRequest = new ServerRequest();
->withServerParams($request->server) $serverRequest->withData($request->getData());
->withServerTarget($request) $serverRequest->withServerParams($request->server);
->withCookieParams($request->cookie) $serverRequest->withServerTarget($request);
->withUri(Uri::parseUri($request)) $serverRequest->withCookieParams($request->cookie);
->withBody(new Stream($request->getContent())) $serverRequest->withUri(Uri::parseUri($request));
->withQueryParams($request->get ?? []) $serverRequest->withQueryParams($request->get ?? []);
->withUploadedFiles($request->files ?? []) $serverRequest->withUploadedFiles($request->files ?? []);
->withMethod($request->getMethod()) $serverRequest->withMethod($request->getMethod());
->withParsedBody(function (StreamInterface $stream, ?array $posts) { $serverRequest->withParsedBody($request->post);
try { return $serverRequest;
$content = Parse::data($stream->getContents());
if (!empty($content)) {
return $content;
}
return $posts;
} catch (\Throwable $throwable) {
return $posts;
}
});
} }
@@ -145,7 +140,7 @@ class ServerRequest extends Request implements ServerRequestInterface
public function getParsedBody(): object|array|null public function getParsedBody(): object|array|null
{ {
if (empty($this->parsedBody)) { if (empty($this->parsedBody)) {
$callback = Context::getContext('with.parsed.body.callback'); $callback = Context::getContext(self::PARSE_BODY);
$this->parsedBody = $callback($this->getBody(), $this->serverTarget->post); $this->parsedBody = $callback($this->getBody(), $this->serverTarget->post);
} }
@@ -159,7 +154,14 @@ class ServerRequest extends Request implements ServerRequestInterface
*/ */
public function withParsedBody($data): ServerRequestInterface public function withParsedBody($data): ServerRequestInterface
{ {
Context::setContext('with.parsed.body.callback', $data); $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 $this;
} }
+1
View File
@@ -54,6 +54,7 @@ class Uri implements UriInterface
return $this->host; return $this->host;
} }
/** /**
* @return int|null * @return int|null
*/ */
+1
View File
@@ -52,6 +52,7 @@ class Request implements RequestInterface
/** /**
* @param \Swoole\Http\Request $request * @param \Swoole\Http\Request $request
* @return Request * @return Request
* @throws \Exception
*/ */
public static function create(\Swoole\Http\Request $request): Request public static function create(\Swoole\Http\Request $request): Request
{ {
+1 -1
View File
@@ -42,7 +42,7 @@ class Http extends \Server\Abstracts\Http implements OnClose, OnConnect
public function onRequest(Request $request, Response $response): void public function onRequest(Request $request, Response $response): void
{ {
try { try {
$node = $this->router->Branch_search($Psr7Request = ScRequest::create($request)); $node = $this->router->radix_tree($Psr7Request = ScRequest::create($request));
if (!($node instanceof Node)) { if (!($node instanceof Node)) {
throw new RequestException(Constant::STATUS_404_MESSAGE, 404); throw new RequestException(Constant::STATUS_404_MESSAGE, 404);
} }