From 86cc6de800e22d7ee2dc02d4248aebd01def1103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Debussch=C3=A8re?= Date: Thu, 24 Jul 2025 23:27:51 +0200 Subject: [PATCH 1/3] feat: new runner class --- .github/workflows/php.yml | 2 +- composer.json | 4 +- phpstan.neon | 3 + src/Emitter.php | 65 +++++++++++++++++++ src/EmitterInterface.php | 17 +++++ src/{RequestHandler => }/RequestHandler.php | 13 +++- src/RequestHandler/Emitter.php | 40 ------------ .../RequestHandlerRuntimeException.php | 18 ----- .../RequestHandlerInterface.php | 6 +- src/RequestHandlerRunner.php | 52 +++++++++++++++ src/RequestHandlerRunnerInterface.php | 13 ++++ src/RequestHandlerRuntimeException.php | 29 +++++++++ 12 files changed, 195 insertions(+), 67 deletions(-) create mode 100644 phpstan.neon create mode 100644 src/Emitter.php create mode 100644 src/EmitterInterface.php rename src/{RequestHandler => }/RequestHandler.php (71%) delete mode 100644 src/RequestHandler/Emitter.php delete mode 100644 src/RequestHandler/Exception/RequestHandlerRuntimeException.php rename src/{RequestHandler => }/RequestHandlerInterface.php (85%) create mode 100644 src/RequestHandlerRunner.php create mode 100644 src/RequestHandlerRunnerInterface.php create mode 100644 src/RequestHandlerRuntimeException.php diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 3c0ce56..6b9f40d 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -40,4 +40,4 @@ jobs: run: ./vendor/bin/phpunit tests --testdox - name: Run static analysis - run: ./vendor/bin/phpstan analyse src --level 6 --no-progress --no-interaction \ No newline at end of file + run: ./vendor/bin/phpstan analyse src --no-progress --no-interaction diff --git a/composer.json b/composer.json index 476fb3b..c96a64f 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ }, "autoload": { "psr-4": { - "Borsch\\": "src/" + "Borsch\\RequestHandler\\": "src/" } }, "autoload-dev": { @@ -28,4 +28,4 @@ "BorschTest\\": "tests/" } } -} \ No newline at end of file +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..ad2c08d --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,3 @@ +parameters: + level: 6 + treatPhpDocTypesAsCertain: false diff --git a/src/Emitter.php b/src/Emitter.php new file mode 100644 index 0000000..43e6e40 --- /dev/null +++ b/src/Emitter.php @@ -0,0 +1,65 @@ +emitHeaders($response); + $this->emitStatusLine($response); + $this->emitBody($response->getBody()); + + return true; + } + + private function emitHeaders(ResponseInterface $response): void + { + foreach ($response->getHeaders() as $name => $values) { + foreach ($values as $value) { + header(sprintf( + '%s: %s', + ucwords($name, '-'), $value), + false + ); + } + } + } + + private function emitStatusLine(ResponseInterface $response): void + { + $http_line = sprintf( + 'HTTP/%s %s %s', + $response->getProtocolVersion(), + $response->getStatusCode(), + $response->getReasonPhrase() + ); + + header($http_line, true, $response->getStatusCode()); + } + + private function emitBody(StreamInterface $stream): void + { + if ($stream->isSeekable()) { + $stream->rewind(); + } + + if (!$stream->isReadable()) { + echo $stream; + return; + } + + $length = 1024 * 8; + while (!$stream->eof()) { + echo $stream->read($length); + } + } +} diff --git a/src/EmitterInterface.php b/src/EmitterInterface.php new file mode 100644 index 0000000..6c7c781 --- /dev/null +++ b/src/EmitterInterface.php @@ -0,0 +1,17 @@ +stack->shift()->process($request, $this); + $middleware = $this->stack->shift(); + if (!$middleware instanceof MiddlewareInterface) { + throw RequestHandlerRuntimeException::invalidMiddleware( + (string)(is_object($middleware) ? get_class($middleware) : gettype($middleware)) + ); + } + + return $middleware->process($request, $this); } } diff --git a/src/RequestHandler/Emitter.php b/src/RequestHandler/Emitter.php deleted file mode 100644 index f55032f..0000000 --- a/src/RequestHandler/Emitter.php +++ /dev/null @@ -1,40 +0,0 @@ -getProtocolVersion(), - $response->getStatusCode(), - $response->getReasonPhrase() - ); - - header($http_line, true, $response->getStatusCode()); - - foreach ($response->getHeaders() as $name => $values) { - foreach ($values as $value) { - header(sprintf('%s: %s', $name, $value), false); - } - } - - $stream = $response->getBody(); - - if ($stream->isSeekable()) { - $stream->rewind(); - } - - $length = 1024 * 8; - while (!$stream->eof()) { - echo $stream->read($length); - } - } -} diff --git a/src/RequestHandler/Exception/RequestHandlerRuntimeException.php b/src/RequestHandler/Exception/RequestHandlerRuntimeException.php deleted file mode 100644 index 7caa458..0000000 --- a/src/RequestHandler/Exception/RequestHandlerRuntimeException.php +++ /dev/null @@ -1,18 +0,0 @@ -server_request_factory = $server_request_factory; + $this->error_response_factory = $error_response_factory; + } + + /** + * @inheritDoc + */ + public function run(): void + { + try { + $request = ($this->server_request_factory)(); + } catch (Throwable $e) { + $this->emitter->emit( + ($this->error_response_factory)($e) + ); + + return; + } + + $this->emitter->emit( + $this->handler->handle($request) + ); + } +} diff --git a/src/RequestHandlerRunnerInterface.php b/src/RequestHandlerRunnerInterface.php new file mode 100644 index 0000000..bcb5911 --- /dev/null +++ b/src/RequestHandlerRunnerInterface.php @@ -0,0 +1,13 @@ + Date: Fri, 25 Jul 2025 18:39:11 +0200 Subject: [PATCH 2/3] upd: Emitter definition --- src/Emitter.php | 7 ++----- src/EmitterInterface.php | 2 +- src/RequestHandlerRunner.php | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Emitter.php b/src/Emitter.php index 43e6e40..f60c969 100644 --- a/src/Emitter.php +++ b/src/Emitter.php @@ -2,8 +2,7 @@ namespace Borsch\RequestHandler; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\{ResponseInterface, StreamInterface}; use function header, sprintf, ucwords; class Emitter implements EmitterInterface @@ -12,13 +11,11 @@ class Emitter implements EmitterInterface /** * @link https://github.com/http-interop/response-sender/blob/master/src/functions.php */ - public function emit(ResponseInterface $response): bool + public function emit(ResponseInterface $response): void { $this->emitHeaders($response); $this->emitStatusLine($response); $this->emitBody($response->getBody()); - - return true; } private function emitHeaders(ResponseInterface $response): void diff --git a/src/EmitterInterface.php b/src/EmitterInterface.php index 6c7c781..fa4fca2 100644 --- a/src/EmitterInterface.php +++ b/src/EmitterInterface.php @@ -13,5 +13,5 @@ interface EmitterInterface * @param ResponseInterface $response The response to emit. * @return bool Returns true on success, false on failure. */ - public function emit(ResponseInterface $response): bool; + public function emit(ResponseInterface $response): void; } diff --git a/src/RequestHandlerRunner.php b/src/RequestHandlerRunner.php index e0cfe60..8a06182 100644 --- a/src/RequestHandlerRunner.php +++ b/src/RequestHandlerRunner.php @@ -2,8 +2,7 @@ namespace Borsch\RequestHandler; -use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Message\{ResponseInterface, ServerRequestInterface}; use Psr\Http\Server\RequestHandlerInterface; use Throwable; From 14aae05b6cf732ac85d69abfd514b3a52e1f5c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Debussch=C3=A8re?= Date: Fri, 25 Jul 2025 18:42:52 +0200 Subject: [PATCH 3/3] fix: phpstan --- src/EmitterInterface.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EmitterInterface.php b/src/EmitterInterface.php index fa4fca2..12ee33c 100644 --- a/src/EmitterInterface.php +++ b/src/EmitterInterface.php @@ -11,7 +11,6 @@ interface EmitterInterface * Emits the given response. * * @param ResponseInterface $response The response to emit. - * @return bool Returns true on success, false on failure. */ public function emit(ResponseInterface $response): void; }