Completed
Push — master ( 9561ee...bb752b )
by Dawid
02:42
created

Server::getServerStats()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Igni\Http;
4
5
use Igni\Exception\RuntimeException;
6
use Igni\Http\Server\ClientStats;
7
use Igni\Http\Server\OnConnect;
8
use Igni\Http\Server\OnShutdown;
9
use Igni\Http\Server\OnStart;
10
use Igni\Http\Server\ServerStats;
11
use Igni\Http\Server\HttpConfiguration;
12
use Igni\Http\Server\Listener;
13
use Igni\Http\Server\OnClose;
14
use Igni\Http\Server\OnRequest;
15
use Swoole;
0 ignored issues
show
Bug introduced by
The type Swoole was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
17
/**
18
 * Http server implementation based on swoole extension.
19
 *
20
 * @package Igni\Http
21
 */
22
class Server
23
{
24
    private const SWOOLE_EXT_NAME = 'swoole';
25
26
    /**
27
     * @var Swoole\Server|null
0 ignored issues
show
Bug introduced by
The type Swoole\Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
     */
29
    private $handler;
30
31
    /**
32
     * @var HttpConfiguration
33
     */
34
    private $settings;
35
36
    /**
37
     * @var Listener[]
38
     */
39
    private $listeners = [];
40
41 6
    public function __construct(HttpConfiguration $settings = null)
42
    {
43 6
        if (!extension_loaded(self::SWOOLE_EXT_NAME)) {
44
            throw new RuntimeException('Could not run server without swoole extension.');
45
        }
46
47 6
        if ($settings === null) {
48 5
            $settings = new HttpConfiguration();
49
        }
50
51 6
        $this->settings = $settings;
52 6
    }
53
54
    /**
55
     * Adds listener that is attached to server once it is run.
56
     *
57
     * @param Listener $listener
58
     */
59 1
    public function addListener(Listener $listener): void
60
    {
61 1
        $this->listeners[] = $listener;
62 1
        if ($this->handler !== null) {
63 1
            $this->attachListener($listener);
64
        }
65 1
    }
66
67
    /**
68
     * Checks if listener exists.
69
     *
70
     * @param Listener $listener
71
     * @return bool
72
     */
73 1
    public function hasListener(Listener $listener): bool
74
    {
75 1
        return in_array($listener, $this->listeners);
76
    }
77
78
    /**
79
     * Returns information about client.
80
     *
81
     * @param int $clientId
82
     * @return ClientStats
83
     */
84 1
    public function getClientStats(int $clientId): ClientStats
85
    {
86 1
        return new ClientStats($this->handler->getClientInfo($clientId));
0 ignored issues
show
Bug introduced by
The method getClientInfo() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
        return new ClientStats($this->handler->/** @scrutinizer ignore-call */ getClientInfo($clientId));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
87
    }
88
89
    /**
90
     * Returns information about server.
91
     *
92
     * @return ServerStats
93
     */
94 1
    public function getServerStats(): ServerStats
95
    {
96 1
        return new ServerStats($this->handler->stats());
97
    }
98
99
    /**
100
     * Starts the server.
101
     */
102 2
    public function start(): void
103
    {
104 2
        if ($this->settings->isSslEnabled()) {
105 1
            $flags = SWOOLE_SOCK_TCP | SWOOLE_SSL;
0 ignored issues
show
Bug introduced by
The constant Igni\Http\SWOOLE_SOCK_TCP was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
106
        } else {
107 1
            $flags = SWOOLE_SOCK_TCP;
108
        }
109
110 2
        $settings = $this->settings->getSettings();
111
112 2
        if (!defined('IS_TEST') || IS_TEST !== true) {
113
            $this->handler = new Swoole\Http\Server($settings['address'], $settings['port'], SWOOLE_PROCESS, $flags);
0 ignored issues
show
Bug introduced by
The constant Igni\Http\SWOOLE_PROCESS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The type Swoole\Http\Server was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
114
        }
115 2
        $this->handler->set($settings);
116
117
        // Attach listeners.
118 2
        foreach ($this->listeners as $listener) {
119 1
            $this->attachListener($listener);
120
        }
121
122
        // Start the server.
123 2
        $this->handler->start();
124 2
    }
125
126
    /**
127
     * Stops the server.
128
     */
129 1
    public function stop(): void
130
    {
131 1
        if ($this->handler !== null) {
132 1
            $this->handler->shutdown();
133 1
            $this->handler = null;
134
        }
135 1
    }
136
137 1
    private function attachListener(Listener $listener): void
138
    {
139 1
        if ($listener instanceof OnRequest) {
140 1
            $this->attachOnRequestListener($listener);
141
        }
142
143 1
        if ($listener instanceof OnConnect) {
144 1
            $this->attachOnConnectListener($listener);
145
        }
146
147 1
        if ($listener instanceof OnClose) {
148
            $this->attachOnCloseListener($listener);
149
        }
150
151 1
        if ($listener instanceof OnShutdown) {
152 1
            $this->attachOnShutdownListener($listener);
153
        }
154
155 1
        if ($listener instanceof OnStart) {
156 1
            $this->attachOnStartListener($listener);
157
        }
158 1
    }
159
160 1
    private function attachOnRequestListener(OnRequest $listener): void
161
    {
162
        $this->handler->on('Request', function(Swoole\Http\Request $request, Swoole\Http\Response $response) use ($listener) {
0 ignored issues
show
Bug introduced by
The type Swoole\Http\Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type Swoole\Http\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
163
            $psrRequest = ServerRequest::fromSwooleRequest($request);
164
            $psrResponse = $listener->onRequest($psrRequest);
165
166
            // Set headers
167
            foreach ($psrResponse->getHeaders() as $name => $values) {
168
                foreach ($values as $value) {
169
                    $response->header($name, $value);
170
                }
171
            }
172
173
            // Status code
174
            $response->status($psrResponse->getStatusCode());
175
176
            // Protect server software header.
177
            $response->header('software-server', '');
178
179
            // End.
180
            $response->end($psrResponse->getBody()->getContents());
181 1
        });
182 1
    }
183
184 1
    private function attachOnConnectListener(OnConnect $listener): void
185
    {
186
        $this->handler->on('Connect', function($handler, $clientId) use ($listener) {
187
            $listener->onConnect($this, $clientId);
188 1
        });
189 1
    }
190
191
    private function attachOnCloseListener(OnClose $listener): void
192
    {
193
        $this->handler->on('Close', function($handler, $clientId) use ($listener) {
194
            $listener->onClose($this, $clientId);
195
        });
196
    }
197
198 1
    private function attachOnShutdownListener(OnShutdown $listener): void
199
    {
200
        $this->handler->on('Shutdown', function() use ($listener) {
201
            $listener->onShutdown($this);
202 1
        });
203 1
    }
204
205 1
    private function attachOnStartListener(OnStart $listener): void
206
    {
207
        $this->handler->on('Start', function() use ($listener) {
208
            $listener->onStart($this);
209 1
        });
210 1
    }
211
}
212