diff --git a/src/Base/CoreMiddleware.php b/src/Base/CoreMiddleware.php index 40eb77e..17e1457 100644 --- a/src/Base/CoreMiddleware.php +++ b/src/Base/CoreMiddleware.php @@ -3,7 +3,7 @@ namespace Kiri\Router\Base; use Exception; -use Kiri\Router\ServerRequest; +use Kiri\Router\Request; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; @@ -18,7 +18,7 @@ class CoreMiddleware implements MiddlewareInterface /** - * @param ServerRequest $request + * @param Request $request * @param RequestHandlerInterface $handler * @return ResponseInterface * @throws Exception diff --git a/src/Constrict/ServerRequest.php b/src/Constrict/ConstrictRequest.php similarity index 57% rename from src/Constrict/ServerRequest.php rename to src/Constrict/ConstrictRequest.php index 4eb3123..cdf6c11 100644 --- a/src/Constrict/ServerRequest.php +++ b/src/Constrict/ConstrictRequest.php @@ -2,22 +2,198 @@ namespace Kiri\Router\Constrict; +use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\UriInterface; -class ServerRequest extends Request implements ServerRequestInterface +class ConstrictRequest extends Message implements RequestInterface, ServerRequestInterface { - private array $posts = []; - - private array $query = []; + /** + * @var string + */ + private string $method; - private array $cookies = []; + /** + * @var UriInterface + */ + private UriInterface $uri; - private array $server = []; + /** + * @var array|object|null + */ + private array|null|object $parsedBody = null; private array $files = []; + private array $queryParams = []; + private array $cookieParams = []; + private array $serverParams = []; + + + /** + * Retrieves the message's request target. + * + * Retrieves the message's request-target either as it will appear (for + * clients), as it appeared at request (for servers), or as it was + * specified for the instance (see withRequestTarget()). + * + * In most cases, this will be the origin-form of the composed URI, + * unless a value was provided to the concrete implementation (see + * withRequestTarget() below). + * + * If no URI is available, and no request-target has been specifically + * provided, this method MUST return the string "/". + * + * @return string + */ + public function getRequestTarget(): string + { + // TODO: Implement getRequestTarget() method. + return (string)$this->getUri(); + } + + + /** + * @param array $headers + * @return $this + */ + public function withHeaders(array $headers): static + { + foreach ($headers as $key => $header) { + $this->withHeader($key, [$header]); + } + return $this; + } + + + /** + * @param string $data + * @return ConstrictRequest + */ + public function withDataHeaders(string $data): static + { + $headers = explode("\r\n\r\n", $data); + $headers = explode("\r\n", $headers[0]); + foreach ($headers as $header) { + $keyValue = explode(': ', $header); + if (!isset($keyValue[1])) { + $keyValue[1] = ''; + } + $keyValue[1] = explode(', ', $keyValue[1]); + $this->withHeader(...$keyValue); + } + return $this; + } + + /** + * Return an instance with the specific request-target. + * + * If the request needs a non-origin-form request-target — e.g., for + * specifying an absolute-form, authority-form, or asterisk-form — + * this method may be used to create an instance with the specified + * request-target, verbatim. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * changed request target. + * + * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various + * request-target forms allowed in request messages) + * @param string $requestTarget + * @return static + */ + public function withRequestTarget(string $requestTarget): static + { + // TODO: Implement withRequestTarget() method. + return $this; + } + + /** + * Retrieves the HTTP method of the request. + * + * @return string Returns the request method. + */ + public function getMethod(): string + { + // TODO: Implement getMethod() method. + return $this->method; + } + + /** + * Return an instance with the provided HTTP method. + * + * While HTTP method names are typically all uppercase characters, HTTP + * method names are case-sensitive and thus implementations SHOULD NOT + * modify the given string. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * changed request method. + * + * @param string $method Case-sensitive method. + * @return static + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + public function withMethod(string $method): static + { + // TODO: Implement withMethod() method. + $this->method = $method; + return $this; + } + + /** + * Retrieves the URI instance. + * + * This method MUST return a UriInterface instance. + * + * @link http://tools.ietf.org/html/rfc3986#section-4.3 + * @return UriInterface Returns a UriInterface instance + * representing the URI of the request. + */ + public function getUri(): UriInterface + { + // TODO: Implement getUri() method. + return $this->uri; + } + + /** + * Returns an instance with the provided URI. + * + * This method MUST update the Host header of the returned request by + * default if the URI contains a host component. If the URI does not + * contain a host component, any pre-existing Host header MUST be carried + * over to the returned request. + * + * You can opt-in to preserving the original state of the Host header by + * setting `$preserveHost` to `true`. When `$preserveHost` is set to + * `true`, this method interacts with the Host header in the following ways: + * + * - If the Host header is missing or empty, and the new URI contains + * a host component, this method MUST update the Host header in the returned + * request. + * - If the Host header is missing or empty, and the new URI does not contain a + * host component, this method MUST NOT update the Host header in the returned + * request. + * - If a Host header is present and non-empty, this method MUST NOT update + * the Host header in the returned request. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new UriInterface instance. + * + * @link http://tools.ietf.org/html/rfc3986#section-4.3 + * @param UriInterface $uri New request URI to use. + * @param bool $preserveHost Preserve the original state of the Host header. + * @return static + */ + public function withUri(UriInterface $uri, bool $preserveHost = false): static + { + // TODO: Implement withUri() method. + $this->uri = $uri; + return $this; + } /** * Retrieve server parameters. @@ -31,7 +207,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function getServerParams(): array { // TODO: Implement getServerParams() method. - return $this->server; + return $this->serverParams = []; } /** @@ -47,7 +223,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function getCookieParams(): array { // TODO: Implement getCookieParams() method. - return $this->cookies; + return $this->cookieParams; } /** @@ -70,7 +246,31 @@ class ServerRequest extends Request implements ServerRequestInterface public function withCookieParams(array $cookies): static { // TODO: Implement withCookieParams() method. - $this->cookies = $cookies; + $this->cookieParams = $cookies; + return $this; + } + + /** + * Return an instance with the specified cookies. + * + * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST + * be compatible with the structure of $_COOKIE. Typically, this data will + * be injected at instantiation. + * + * This method MUST NOT update the related Cookie header of the request + * instance, nor related values in the server params. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * updated cookie values. + * + * @param array $cookies Array of key/value pairs representing cookies. + * @return static + */ + public function withServerParams(array $cookies): static + { + // TODO: Implement withCookieParams() method. + $this->serverParams = $cookies; return $this; } @@ -89,7 +289,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function getQueryParams(): array { // TODO: Implement getQueryParams() method. - return $this->query; + return $this->queryParams; } /** @@ -117,7 +317,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function withQueryParams(array $query): static { // TODO: Implement withQueryParams() method. - $this->query = $query; + $this->queryParams = $query; return $this; } @@ -175,7 +375,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function getParsedBody(): object|array|null { // TODO: Implement getParsedBody() method. - return $this->posts; + return $this->parsedBody; } /** @@ -209,7 +409,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function withParsedBody($data): static { // TODO: Implement withParsedBody() method. - $this->posts = $data; + $this->parsedBody = $data; return $this; } @@ -248,7 +448,7 @@ class ServerRequest extends Request implements ServerRequestInterface public function getAttribute(string $name, $default = null): mixed { // TODO: Implement getAttribute() method. - return $default; + return null; } /** diff --git a/src/Constrict/Response.php b/src/Constrict/ConstrictResponse.php similarity index 97% rename from src/Constrict/Response.php rename to src/Constrict/ConstrictResponse.php index f1e4919..2f4f554 100644 --- a/src/Constrict/Response.php +++ b/src/Constrict/ConstrictResponse.php @@ -5,7 +5,7 @@ namespace Kiri\Router\Constrict; use Kiri\Router\ContentType; use Psr\Http\Message\ResponseInterface; -class Response extends Message implements ResponseInterface +class ConstrictResponse extends Message implements ResponseInterface { diff --git a/src/Constrict/Request.php b/src/Constrict/Request.php deleted file mode 100644 index 1f2e3da..0000000 --- a/src/Constrict/Request.php +++ /dev/null @@ -1,166 +0,0 @@ -getUri(); - } - - - /** - * @param array $headers - * @return $this - */ - public function withHeaders(array $headers): static - { - foreach ($headers as $key => $header) { - $this->withHeader($key, [$header]); - } - return $this; - } - - /** - * Return an instance with the specific request-target. - * - * If the request needs a non-origin-form request-target — e.g., for - * specifying an absolute-form, authority-form, or asterisk-form — - * this method may be used to create an instance with the specified - * request-target, verbatim. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * changed request target. - * - * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various - * request-target forms allowed in request messages) - * @param string $requestTarget - * @return static - */ - public function withRequestTarget(string $requestTarget): static - { - // TODO: Implement withRequestTarget() method. - return $this; - } - - /** - * Retrieves the HTTP method of the request. - * - * @return string Returns the request method. - */ - public function getMethod(): string - { - // TODO: Implement getMethod() method. - return $this->method; - } - - /** - * Return an instance with the provided HTTP method. - * - * While HTTP method names are typically all uppercase characters, HTTP - * method names are case-sensitive and thus implementations SHOULD NOT - * modify the given string. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * changed request method. - * - * @param string $method Case-sensitive method. - * @return static - * @throws \InvalidArgumentException for invalid HTTP methods. - */ - public function withMethod(string $method): static - { - // TODO: Implement withMethod() method. - $this->method = $method; - return $this; - } - - /** - * Retrieves the URI instance. - * - * This method MUST return a UriInterface instance. - * - * @link http://tools.ietf.org/html/rfc3986#section-4.3 - * @return UriInterface Returns a UriInterface instance - * representing the URI of the request. - */ - public function getUri(): UriInterface - { - // TODO: Implement getUri() method. - return $this->uri; - } - - /** - * Returns an instance with the provided URI. - * - * This method MUST update the Host header of the returned request by - * default if the URI contains a host component. If the URI does not - * contain a host component, any pre-existing Host header MUST be carried - * over to the returned request. - * - * You can opt-in to preserving the original state of the Host header by - * setting `$preserveHost` to `true`. When `$preserveHost` is set to - * `true`, this method interacts with the Host header in the following ways: - * - * - If the Host header is missing or empty, and the new URI contains - * a host component, this method MUST update the Host header in the returned - * request. - * - If the Host header is missing or empty, and the new URI does not contain a - * host component, this method MUST NOT update the Host header in the returned - * request. - * - If a Host header is present and non-empty, this method MUST NOT update - * the Host header in the returned request. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new UriInterface instance. - * - * @link http://tools.ietf.org/html/rfc3986#section-4.3 - * @param UriInterface $uri New request URI to use. - * @param bool $preserveHost Preserve the original state of the Host header. - * @return static - */ - public function withUri(UriInterface $uri, bool $preserveHost = false): static - { - // TODO: Implement withUri() method. - $this->uri = $uri; - return $this; - } -} diff --git a/src/HttpResponseEmitter.php b/src/HttpResponseEmitter.php index 8de1f81..4df4f27 100644 --- a/src/HttpResponseEmitter.php +++ b/src/HttpResponseEmitter.php @@ -35,7 +35,7 @@ class HttpResponseEmitter implements ResponseEmitter private function writeParams(ResponseInterface $proxy, object $response): void { $response->setStatusCode($proxy->getStatusCode()); - /** @var ServerRequest $request */ + /** @var Request $request */ $request = \Kiri::service()->get('request'); foreach ($request->getHeaders() as $name => $header) { $response->header($name, implode(', ', $header)); diff --git a/src/ServerRequest.php b/src/Request.php similarity index 97% rename from src/ServerRequest.php rename to src/Request.php index d0c5b8a..fa7afa1 100644 --- a/src/ServerRequest.php +++ b/src/Request.php @@ -3,9 +3,7 @@ namespace Kiri\Router; use Kiri\Di\Context; -use Kiri\Message\Stream; use Kiri\Router\Base\ExceptionHandlerDispatcher; -use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UriInterface; @@ -14,7 +12,7 @@ use Psr\Http\Message\UriInterface; /** * @property-read bool $isPost */ -class ServerRequest implements ServerRequestInterface +class Request implements ServerRequestInterface { @@ -192,19 +190,19 @@ class ServerRequest implements ServerRequestInterface * @param string $data * @return ServerRequestInterface */ - public function withHeaders(string $data): ServerRequestInterface + public function withDataHeaders(string $data): ServerRequestInterface { - $headers = explode("\r\n\r\n", $data); - $headers = explode("\r\n", $headers[0]); - foreach ($headers as $header) { - $keyValue = explode(': ', $header); - if (!isset($keyValue[1])) { - $keyValue[1] = ''; - } - $keyValue[1] = explode(', ', $keyValue[1]); - $this->withHeader(...$keyValue); - } - return $this; + return $this->__call__(__FUNCTION__, $data); + } + + + /** + * @param array $headers + * @return ServerRequestInterface + */ + public function withHeaders(array $headers): ServerRequestInterface + { + return $this->__call__(__FUNCTION__, $headers); } diff --git a/src/Server.php b/src/Server.php index 779fd41..2c17841 100644 --- a/src/Server.php +++ b/src/Server.php @@ -16,7 +16,8 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Swoole\Http\Request; use Swoole\Http\Response; -use Kiri\Router\Constrict\Response as KrcResponse; +use Kiri\Router\Constrict\ConstrictRequest; +use Kiri\Router\Constrict\ConstrictResponse; use Kiri\Router\Constrict\Uri; use Kiri\Router\Interface\OnRequestInterface; use Kiri\Router\Base\ExceptionHandlerDispatcher; @@ -84,7 +85,7 @@ class Server extends AbstractServer implements OnRequestInterface public function onRequest(Request $request, Response $response): void { try { - /** @var ServerRequest $PsrRequest */ + /** @var Request $PsrRequest */ $PsrRequest = $this->initRequestAndResponse($request); $dispatcher = $this->router->query($request->server['request_uri'], $request->getMethod()); @@ -92,7 +93,7 @@ class Server extends AbstractServer implements OnRequestInterface $PsrResponse = (new HttpRequestHandler([], $dispatcher))->handle($PsrRequest); } catch (\Throwable $throwable) { $this->logger->error($throwable->getMessage(), [$throwable]); - $PsrResponse = $this->exception->emit($throwable, di(Constrict\Response::class)); + $PsrResponse = $this->exception->emit($throwable, di(ConstrictResponse::class)); } finally { $this->emitter->sender($PsrResponse, $response); } @@ -109,11 +110,11 @@ class Server extends AbstractServer implements OnRequestInterface /** @var \Kiri\Router\Response $response */ $response = Kiri::service()->get('response'); - /** @var KrcResponse $PsrResponse */ - $PsrResponse = Context::set(ResponseInterface::class, new KrcResponse()); + /** @var ConstrictResponse $PsrResponse */ + $PsrResponse = Context::set(ResponseInterface::class, new ConstrictResponse()); $PsrResponse->withContentType($response->contentType); - $serverRequest = (new ServerRequest())->withHeaders($request->getData()) + $serverRequest = (new ConstrictRequest())->withDataHeaders($request->getData()) ->withUri(Uri::parse($request)) ->withProtocolVersion($request->server['server_protocol']) ->withCookieParams($request->cookie ?? []) @@ -122,7 +123,7 @@ class Server extends AbstractServer implements OnRequestInterface ->withMethod($request->getMethod()) ->withParsedBody($request->post); - /** @var ServerRequest $PsrRequest */ + /** @var Request $PsrRequest */ return Context::set(RequestInterface::class, $serverRequest); } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index c6044c7..8842643 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -3,7 +3,7 @@ namespace Kiri\Router\Validator; use Kiri\Router\Interface\ValidatorInterface; -use Kiri\Router\ServerRequest; +use Kiri\Router\Request; use Psr\Http\Message\ServerRequestInterface; class Validator @@ -36,10 +36,10 @@ class Validator /** - * @param ServerRequestInterface|ServerRequest $request + * @param ServerRequestInterface|Request $request * @return Validator */ - public function bindData(ServerRequestInterface|ServerRequest $request): static + public function bindData(ServerRequestInterface|Request $request): static { if ($request->isPost) { $data = $request->getParsedBody();