Passed
Push — master ( 465b21...de1506 )
by Koldo
05:36
created

ReactRequestHandlerRunner::run()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 14
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 22
ccs 0
cts 16
cp 0
crap 6
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\React\Runner;
6
7
use Antidot\Application\Http\Middleware\Pipeline;
8
use Antidot\React\CallablePipeline;
9
use Psr\Http\Message\ResponseInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use React\EventLoop\LoopInterface;
12
use React\Http\Server;
13
use React\Socket\ServerInterface;
14
use Zend\HttpHandlerRunner\Emitter\EmitterStack;
15
use Zend\HttpHandlerRunner\RequestHandlerRunner;
16
17
class ReactRequestHandlerRunner extends RequestHandlerRunner
18
{
19
    /**
20
     * A request handler to run as the application.
21
     *
22
     * @var CallablePipeline
23
     */
24
    private $handler;
25
26
    /**
27
     * A factory capable of generating an error response in the scenario that
28
     * the $serverRequestFactory raises an exception during generation of the
29
     * request instance.
30
     *
31
     * The factory will receive the Throwable or Exception that caused the error,
32
     * and must return a Psr\Http\Message\ResponseInterface instance.
33
     *
34
     * @var callable
35
     */
36
    private $serverRequestErrorResponseGenerator;
0 ignored issues
show
introduced by
The private property $serverRequestErrorResponseGenerator is not used, and could be removed.
Loading history...
37
38
    /**
39
     * A factory capable of generating a Psr\Http\Message\ServerRequestInterface instance.
40
     * The factory will not receive any arguments.
41
     *
42
     * @var callable
43
     */
44
    private $serverRequestFactory;
0 ignored issues
show
introduced by
The private property $serverRequestFactory is not used, and could be removed.
Loading history...
45
46
    /**
47
     * React Http Server
48
     *
49
     * @var ServerInterface
50
     */
51
    private $socketServer;
52
53
    /**
54
     * @var LoopInterface
55
     */
56
    private $loop;
57
    /** @var callable * */
58
    private $errorResponseGenerator;
59
60
    public function __construct(
61
        CallablePipeline $handler,
62
        EmitterStack $emitterStack,
63
        callable $errorResponseGenerator,
64
        ServerInterface $socketServer,
65
        LoopInterface $loop
66
    ) {
67
        parent::__construct(
68
            $handler,
69
            $emitterStack,
70
            function () {
71
            },
72
            $errorResponseGenerator
73
        );
74
75
        $this->handler = $handler;
76
        $this->loop = $loop;
77
        $this->socketServer = $socketServer;
78
        $this->errorResponseGenerator = $errorResponseGenerator;
79
    }
80
81
    public function run(): void
82
    {
83
        $server = new Server(function (ServerRequestInterface $request) {
84
            $next = clone $this->handler;
85
            return ($this->handler->__invoke($request, $next))->then(function (ResponseInterface $response) use (
86
                $request
87
            ) {
88
                $this->printResponse($request, $response);
89
                return $response;
90
            }, function (\Throwable $e) use ($request) {
91
                $errorResponseGenerator = $this->errorResponseGenerator;
92
                $this->printErrorResponse($request);
93
94
                return $errorResponseGenerator(null === $e->getPrevious() ? $e : $e->getPrevious());
95
            });
96
        });
97
        $server->on('error', function (\Throwable $e) {
98
            $this->printServerError($e);
99
        });
100
        $server->listen($this->socketServer);
101
102
        $this->loop->run();
103
    }
104
105
    private function printResponse(ServerRequestInterface $request, ResponseInterface $response): void
106
    {
107
        if (0 === strpos((string)$response->getStatusCode(), '20')) {
108
            echo sprintf(
109
                "[%s] \033[0;32m%s\033[0m - %s",
110
                $request->getMethod(),
111
                $response->getStatusCode(),
112
                $request->getUri()->getPath()
113
            ) . PHP_EOL;
114
        } else {
115
            echo sprintf(
116
                "[%s] \033[0;33m%s\033[0m - %s",
117
                $request->getMethod(),
118
                $response->getStatusCode(),
119
                $request->getUri()->getPath()
120
            ) . PHP_EOL;
121
        }
122
    }
123
124
    private function printErrorResponse(ServerRequestInterface $request): void
125
    {
126
        echo sprintf(
127
            "[%s] \033[0;31m500\033[0m - %s",
128
            $request->getMethod(),
129
            $request->getUri()->getPath()
130
        ) . PHP_EOL;
131
    }
132
133
    private function printServerError(\Throwable $e): void
134
    {
135
        $e = null === $e->getPrevious() ? $e : $e->getPrevious();
136
137
        echo sprintf(
138
            '[%s]: Server error occurred: %s, in file %s in line %s',
139
            get_class($e),
140
            $e->getMessage(),
141
            $e->getFile(),
142
            $e->getLine()
143
        ) . PHP_EOL;
144
        echo sprintf(
145
            '[%s]: %s',
146
            get_class($e),
147
            $e->getTraceAsString()
148
        ) . PHP_EOL;
149
    }
150
}
151