This commit is contained in:
2023-10-17 14:50:46 +08:00
parent 30da8e7b37
commit bfbdb1e7ce
12 changed files with 251 additions and 57 deletions
+13
View File
@@ -71,6 +71,19 @@ class ConstrictResponse extends Message implements ResponseInterface
}
/**
* @param string $content
* @param int $statusCode
* @param ContentType $contentType
* @return $this
*/
public function raw(string $content, int $statusCode = 200, ContentType $contentType = ContentType::JSON): static
{
$this->getBody()->write($content);
return $this->withContentType($contentType)->withStatus($statusCode);
}
/**
* @param string $content
* @param int $statusCode
+6 -2
View File
@@ -73,8 +73,12 @@ class ControllerInterpreter
*/
public function resolveMethod(object $class, string|\ReflectionMethod $reflectionMethod, ReflectionClass $reflectionClass): Handler
{
$returnType = $reflectionMethod->getReturnType();
if ($returnType instanceof \ReflectionUnionType) {
throw new Exception("Return type error, cannot be multi type.");
}
if (empty($reflectionMethod)) {
return new Handler([$class, $reflectionMethod], [], $reflectionMethod->getReturnType());
return new Handler([$class, $reflectionMethod], [], $returnType);
}
if (is_string($reflectionMethod)) {
$reflectionMethod = $reflectionClass->getMethod($reflectionMethod);
@@ -83,7 +87,7 @@ class ControllerInterpreter
$container = \Kiri::getDi();
$parameters = $container->getMethodParams($reflectionMethod);
return new Handler([$class, $reflectionMethod->getName()], $parameters, $reflectionMethod->getReturnType());
return new Handler([$class, $reflectionMethod->getName()], $parameters, $returnType);
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace Kiri\Router\Format;
use Kiri\Router\Constrict\Stream;
use Kiri\Router\ContentType;
use Psr\Http\Message\ResponseInterface;
class ArrayFormat implements IFormat
{
/**
* @param $result
* @return ResponseInterface
*/
public function call($result): ResponseInterface
{
$result = json_encode($result);
return \response()->withContentType(ContentType::JSON)
->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE)));
}
}
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace Kiri\Router\Format;
use Psr\Http\Message\ResponseInterface;
interface IFormat
{
/**
* @param $result
* @return ResponseInterface
*/
public function call($result): ResponseInterface;
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace Kiri\Router\Format;
use Kiri\Router\Constrict\Stream;
use Kiri\Router\ContentType;
use Psr\Http\Message\ResponseInterface;
class MixedFormat implements IFormat
{
/**
* @param mixed $result
* @return ResponseInterface
*/
public function call(mixed $result): ResponseInterface
{
if (is_object($result)) {
return \response()->withBody(new Stream('[object]'));
}
if (is_array($result)) {
return \response()->withContentType(ContentType::JSON)->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE)));
} else {
return \response()->withBody(new Stream($result));
}
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace Kiri\Router\Format;
use Kiri\Router\Constrict\Stream;
use Kiri\Router\ContentType;
use Psr\Http\Message\ResponseInterface;
class OtherFormat implements IFormat
{
/**
* @param mixed $result
* @return ResponseInterface
*/
public function call(mixed $result): ResponseInterface
{
return \response()->withBody(new Stream($result));
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Kiri\Router\Format;
use Psr\Http\Message\ResponseInterface;
class ResponseFormat implements IFormat
{
/**
* @inheritDoc
*/
public function call($result): ResponseInterface
{
// TODO: Implement call() method.
return $result;
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Kiri\Router\Format;
use Psr\Http\Message\ResponseInterface;
class VoidFormat implements IFormat
{
/**
* @param $result
* @return ResponseInterface
*/
public function call($result): ResponseInterface
{
// TODO: Implement call() method.
return response();
}
}
+33 -29
View File
@@ -5,24 +5,51 @@ namespace Kiri\Router;
use Closure;
use Kiri\Router\Constrict\Stream;
use Kiri\Router\Format\ArrayFormat;
use Kiri\Router\Format\IFormat;
use Kiri\Router\Format\MixedFormat;
use Kiri\Router\Format\OtherFormat;
use Kiri\Router\Format\VoidFormat;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use ReflectionException;
use ReflectionIntersectionType;
use ReflectionNamedType;
use ReflectionUnionType;
use ReflectionType;
class Handler implements RequestHandlerInterface
{
/**
* @var array|string[]
*/
protected array $types = [
'array' => ArrayFormat::class,
'mixed' => MixedFormat::class,
'object' => MixedFormat::class,
'int' => OtherFormat::class,
'string' => OtherFormat::class,
'bool' => OtherFormat::class,
'void' => VoidFormat::class,
];
/**
* @var IFormat
*/
protected IFormat $format;
/**
* @param array|Closure $handler
* @param array $parameter
* @param ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $responseType
* @param ReflectionNamedType $reflectionType
* @throws ReflectionException
*/
public function __construct(public array|Closure $handler, public array $parameter, public ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $responseType)
public function __construct(public array|Closure $handler, public array $parameter, public ReflectionNamedType $reflectionType)
{
$this->format = di($this->reflectionType->getName());
}
@@ -79,32 +106,9 @@ class Handler implements RequestHandlerInterface
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
// TODO: Implement handle() method.
if ($this->responseType->getName() !== 'void') {
return $this->typeEncode();
}
call_user_func($this->handler, ...$this->parameter);
return \response();
}
$data = call_user_func($this->handler, ...$this->parameter);
/**
* @return ResponseInterface
*/
protected function typeEncode(): ResponseInterface
{
$result = call_user_func($this->handler, ...$this->parameter);
if ($result instanceof ResponseInterface) {
return $result;
}
if (is_object($result)) {
return \response()->withBody(new Stream('[object]'));
}
if (is_array($result)) {
return \response()->withContentType(ContentType::JSON)->withBody(new Stream(json_encode($result, JSON_UNESCAPED_UNICODE)));
} else {
return \response()->withBody(new Stream($result));
}
return call_user_func([$this->format, 'call'], $data);
}
}
+12
View File
@@ -390,6 +390,18 @@ class Response implements ResponseInterface
return $this->__call__(__FUNCTION__);
}
/**
* @param string $content
* @param int $statusCode
* @param ContentType $contentType
* @return ResponseInterface
*/
public function raw(string $content, int $statusCode = 200, ContentType $contentType = ContentType::JSON): ResponseInterface
{
return $this->__call__(__FUNCTION__, $content, $statusCode, $contentType);
}
/**
* Return an instance with the specified status code and, optionally, reason phrase.
*
+24 -9
View File
@@ -19,15 +19,16 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface
/**
* @param Response $proxy
* @param object $response
* @param object $request
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ReflectionException
*/
public function sender(ResponseInterface $proxy, object $response): void
public function sender(ResponseInterface $proxy, object $response, object $request): void
{
// TODO: Implement sender() method.
$this->writeParams($proxy, $response);
$this->writeParams($proxy, $response, $request);
$proxy->end($response);
@@ -38,24 +39,38 @@ class SwooleHttpResponseEmitter implements ResponseEmitterInterface
/**
* @param Response $proxy
* @param object $response
* @param object $request
* @return void
*/
private function writeParams(ResponseInterface $proxy, object $response): void
private function writeParams(ResponseInterface $proxy, object $response, object $request): void
{
$response->setStatusCode($proxy->getStatusCode());
foreach ($proxy->getHeaders() as $name => $header) {
$headers = $proxy->getHeaders();
if (count($headers) < 1) {
foreach ($headers as $name => $header) {
$response->header($name, $header);
}
foreach ($proxy->getCookieParams() as $cookie) {
}
$cookieParams = $proxy->getCookieParams();
if (count($cookieParams) < 1) {
foreach ($cookieParams as $cookie) {
$response->setCookie(...$cookie);
}
$request = \request();
$response->header('Run-Time', microtime(true) - +$request->getServerParam('request_time_float'));
}
$response->header('Run-Time', $this->getRunTime($request));
$response->header('Server', 'swoole');
$response->header('Swoole-Version', swoole_version());
}
/**
* @param object $request
* @return float
*/
protected function getRunTime(object $request): float
{
return microtime(true) - +$request->getServerParam('request_time_float');
}
}
+13 -1
View File
@@ -16,18 +16,30 @@ class SwowHttpResponseEmitter implements ResponseEmitterInterface
/**
* @param Response $proxy
* @param object $response
* @param object $request
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws ReflectionException
*/
public function sender(ResponseInterface $proxy, object $response): void
public function sender(ResponseInterface $proxy, object $response, object $request): void
{
// TODO: Implement sender() method.
$proxy->withHeader('Server', 'Swow');
$proxy->withHeader('Run-Time', $this->getRunTime($request));
$response->sendHttpResponse($proxy);
event(new OnAfterRequest());
}
/**
* @param object $request
* @return float
*/
protected function getRunTime(object $request): float
{
return microtime(true) - +$request->getServerParam('request_time_float');
}
}