From c9ea90ea4326852ec530c0f17912c78cd2fceebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 3 Oct 2023 12:56:31 +0000 Subject: [PATCH] Add swoole resources --- src/Http/Adapter/Swoole/Server.php | 4 +-- src/Http/Http.php | 42 ++++++++++++++++++------------ tests/e2e/ResponseSwooleTest.php | 6 +++++ tests/e2e/server_swoole.php | 14 ++++++++++ 4 files changed, 47 insertions(+), 19 deletions(-) mode change 100644 => 100755 tests/e2e/ResponseSwooleTest.php mode change 100644 => 100755 tests/e2e/server_swoole.php diff --git a/src/Http/Adapter/Swoole/Server.php b/src/Http/Adapter/Swoole/Server.php index 4e79c949..b13a522d 100755 --- a/src/Http/Adapter/Swoole/Server.php +++ b/src/Http/Adapter/Swoole/Server.php @@ -34,8 +34,8 @@ public function onRequest(callable $callback) $this->server->handle('/', function (SwooleRequest $request, SwooleResponse $response) use ($callback) { $context = \strval(Coroutine::getCid()); - Http::setResource('swooleRequest', fn () => $request); - Http::setResource('swooleResponse', fn () => $response); + Http::setResource('swooleRequest', fn () => $request, [], $context); + Http::setResource('swooleResponse', fn () => $response, [], $context); call_user_func($callback, new Request($request), new Response($response), $context); }); diff --git a/src/Http/Http.php b/src/Http/Http.php index aad8883b..9d90b353 100755 --- a/src/Http/Http.php +++ b/src/Http/Http.php @@ -349,18 +349,23 @@ public function getResource(string $name, string $context = 'utopia', bool $fres $this->resources[$context] ??= []; - if (!\array_key_exists($name, $this->resources[$context]) || $fresh || (self::$resourcesCallbacks[$name]['reset'][$context] ?? true)) { - if (!\array_key_exists($name, self::$resourcesCallbacks)) { + $resourcesCallback = &self::$resourcesCallbacks[$context] ?? []; + if(empty($resourcesCallback) || !\array_key_exists($name, $resourcesCallback)) { + $resourcesCallback = &self::$resourcesCallbacks['utopia']; + } + + if (!\array_key_exists($name, $this->resources[$context]) || $fresh || ($resourcesCallback[$name]['reset'][$context] ?? true)) { + if (!\array_key_exists($name, $resourcesCallback)) { throw new Exception('Failed to find resource: "' . $name . '"'); } $this->resources[$context][$name] = \call_user_func_array( - self::$resourcesCallbacks[$name]['callback'], - $this->getResources(self::$resourcesCallbacks[$name]['injections'], $context) + $resourcesCallback[$name]['callback'], + $this->getResources($resourcesCallback[$name]['injections'], $context) ); } - self::$resourcesCallbacks[$name]['reset'][$context] = false; + $resourcesCallback[$name]['reset'][$context] = false; return $this->resources[$context][$name]; } @@ -391,12 +396,15 @@ public function getResources(array $list, string $context): array * * @throws Exception */ - public static function setResource(string $name, callable $callback, array $injections = []): void + public static function setResource(string $name, callable $callback, array $injections = [], string $context = 'utopia'): void { if ($name === 'utopia') { throw new Exception("'utopia' is a reserved keyword.", 500); } - self::$resourcesCallbacks[$name] = ['callback' => $callback, 'injections' => $injections, 'resets' => []]; + + self::$resourcesCallbacks[$context] ??= []; + + self::$resourcesCallbacks[$context][$name] = ['callback' => $callback, 'injections' => $injections, 'resets' => []]; } /** @@ -697,7 +705,7 @@ public function execute(Route $route, Request $request, string $context): static } } } catch (\Throwable $e) { - self::setResource('error', fn () => $e); + self::setResource('error', fn () => $e, [], $context); foreach ($groups as $group) { foreach (self::$errors as $error) { // Group error hooks @@ -787,11 +795,11 @@ public function run(Request $request, Response $response, string $context): stat $this->resources[$context]['request'] = $request; $this->resources[$context]['response'] = $response; - self::setResource('context', fn () => $context); + self::setResource('context', fn () => $context, [], $context); - self::setResource('request', fn () => $request); + self::setResource('request', fn () => $request, [], $context); - self::setResource('response', fn () => $response); + self::setResource('response', fn () => $response, [], $context); try { @@ -800,7 +808,7 @@ public function run(Request $request, Response $response, string $context): stat \call_user_func_array($hook->getAction(), $arguments); } } catch(\Exception $e) { - self::setResource('error', fn () => $e); + self::setResource('error', fn () => $e, [], $context); foreach (self::$errors as $error) { // Global error hooks if (in_array('*', $error->getGroups())) { @@ -829,7 +837,7 @@ public function run(Request $request, Response $response, string $context): stat $route = $this->match($request); $groups = ($route instanceof Route) ? $route->getGroups() : []; - self::setResource('route', fn () => $route); + self::setResource('route', fn () => $route, [], $context); if (self::REQUEST_METHOD_HEAD == $method) { $method = self::REQUEST_METHOD_GET; @@ -859,7 +867,7 @@ public function run(Request $request, Response $response, string $context): stat if (in_array('*', $error->getGroups())) { self::setResource('error', function () use ($e) { return $e; - }); + }, [], $context); \call_user_func_array($error->getAction(), $this->getArguments($error, $context, [], $request->getParams())); } } @@ -874,7 +882,7 @@ public function run(Request $request, Response $response, string $context): stat $path = \parse_url($request->getURI(), PHP_URL_PATH); $route->path($path); - self::setResource('route', fn () => $route); + self::setResource('route', fn () => $route, [], $context); } if (null !== $route) { @@ -899,7 +907,7 @@ public function run(Request $request, Response $response, string $context): stat if (in_array('*', $error->getGroups())) { self::setResource('error', function () use ($e) { return $e; - }); + }, [], $context); \call_user_func_array($error->getAction(), $this->getArguments($error, $context, [], $request->getParams())); } } @@ -909,7 +917,7 @@ public function run(Request $request, Response $response, string $context): stat if (in_array('*', $error->getGroups())) { self::setResource('error', function () { return new Exception('Not Found', 404); - }); + }, [], $context); \call_user_func_array($error->getAction(), $this->getArguments($error, $context, [], $request->getParams())); } } diff --git a/tests/e2e/ResponseSwooleTest.php b/tests/e2e/ResponseSwooleTest.php old mode 100644 new mode 100755 index 6d793b90..0851554a --- a/tests/e2e/ResponseSwooleTest.php +++ b/tests/e2e/ResponseSwooleTest.php @@ -14,4 +14,10 @@ public function setUp(): void { $this->client = new Client('http://swoole'); } + + public function testSwooleResources(): void + { + $response = $this->client->call(Client::METHOD_DELETE, '/swoole-test'); + $this->assertEquals('DELETE', $response['body']); + } } diff --git a/tests/e2e/server_swoole.php b/tests/e2e/server_swoole.php old mode 100644 new mode 100755 index 9de631cf..e15e1be4 --- a/tests/e2e/server_swoole.php +++ b/tests/e2e/server_swoole.php @@ -2,11 +2,25 @@ require_once __DIR__.'/init.php'; +use Swoole\Http\Request as SwooleRequest; +use Swoole\Http\Response as SwooleResponse; use Utopia\Http\Adapter\Swoole\Server; use Utopia\Http\Http; use function Swoole\Coroutine\run; +Http::delete('/swoole-test') + ->inject('swooleRequest') + ->inject('swooleResponse') + ->action(function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) { + $method = $swooleRequest->getMethod(); + $swooleResponse->header('Content-Type', 'text/plain'); + $swooleResponse->header('Cache-Control', 'no-cache'); + $swooleResponse->setStatusCode(200); + $swooleResponse->write($method); + $swooleResponse->end(); + }); + $server = new Server('0.0.0.0', '80'); $http = new Http($server, 'UTC');