Issues (32)

src/Powered/Swoole/Server.php (4 issues)

Labels
1
<?php
2
/**
3
 * HTTP server by swoole
4
 * User: moyo
5
 * Date: 28/09/2017
6
 * Time: 5:30 PM
7
 */
8
9
namespace Carno\HTTP\Powered\Swoole;
10
11
use Carno\HTTP\Server\Connection;
12
use Carno\HTTP\Standard\ServerRequest;
13
use Carno\HTTP\Standard\Uri;
14
use Carno\Net\Address;
15
use Carno\Net\Contracts\HTTP;
16
use Carno\Net\Events;
17
use Carno\Serv\Powered\Swoole\ServerBase;
18
use Psr\Http\Message\ResponseInterface as Response;
19
use Swoole\Http\Server as SWHServer;
0 ignored issues
show
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...
20
use Swoole\Http\Request as SWHRequest;
0 ignored issues
show
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...
21
use Swoole\Http\Response as SWHResponse;
0 ignored issues
show
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...
22
23
class Server extends ServerBase implements HTTP
24
{
25
    /**
26
     * @var array
27
     */
28
    protected $acceptEvs = ['request'];
29
30
    /**
31
     * @var array
32
     */
33
    protected $userConfig = [
34
        'http_parse_post' => false,
35
    ];
36
37
    /**
38
     * @var SWHServer
39
     */
40
    private $server = null;
41
42
    /**
43
     * @var SWHResponse[]
44
     */
45
    private $fds = [];
46
47
    /**
48
     * Server constructor.
49
     * @param string $serviced
50
     */
51
    public function __construct(string $serviced)
52
    {
53
        $this->serviced = $serviced;
54
    }
55
56
    /**
57
     * @param Address $address
58
     * @param Events $events
59
     * @param int $workers
60
     * @return HTTP
61
     */
62
    public function listen(Address $address, Events $events, int $workers) : HTTP
63
    {
64
        $this->server = $this->standardServerCreate(
65
            $address,
66
            $events,
67
            SWHServer::class,
68
            ['worker_num' => $workers]
69
        );
70
        return $this;
71
    }
72
73
    /**
74
     */
75
    public function serve() : void
76
    {
77
        $this->server->start();
78
    }
79
80
    /**
81
     */
82
    public function shutdown() : void
83
    {
84
        $this->server->shutdown();
85
    }
86
87
    /**
88
     * @param SWHRequest $request
89
     * @param SWHResponse $response
90
     */
91
    public function evRequest(SWHRequest $request, SWHResponse $response) : void
92
    {
93
        $raw = $request->rawContent();
94
95
        $headers = [];
96
        foreach ($request->header ?: [] as $name => $value) {
97
            $headers[$name] = strpos($value, ',') ? explode(',', $value) : $value;
98
        }
99
100
        $srq = new ServerRequest(
101
            $request->server,
102
            $request->cookie ?? [],
103
            $request->get ?? [],
104
            $request->server['request_method'],
105
            $headers,
106
            $raw ?: null
107
        );
108
109
        $host = $request->header['host'] ?? 'localhost';
110
        $port = null;
111
112
        strpos($host, ':') && list($host, $port) = explode(':', $host);
113
114
        $srq->withUri(
115
            new Uri(
116
                'http',
117
                $host,
118
                $port,
0 ignored issues
show
It seems like $port can also be of type string; however, parameter $port of Carno\HTTP\Standard\Uri::__construct() does only seem to accept integer|null, maybe add an additional type check? ( Ignorable by Annotation )

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

118
                /** @scrutinizer ignore-type */ $port,
Loading history...
119
                $request->server['request_uri'] ?? '/',
120
                $request->server['query_string'] ?? ''
121
            )
122
        );
123
124
        $this->events->notify(
125
            Events\HTTP::REQUESTING,
126
            (new Connection)
127
                ->setID($this->setFdResponse($request->fd, $response))
128
                ->setRequest($srq)
129
                ->setLocal($this->server->host, $request->server['server_port'])
130
                ->setRemote($request->server['remote_addr'], $request->server['remote_port'])
131
                ->setServiced($this->serviced)
132
                ->from($this)
133
        );
134
    }
135
136
    /**
137
     * @param int $conn
138
     * @param Response $response
139
     * @return bool
140
     */
141
    public function reply(int $conn, Response $response) : bool
142
    {
143
        $replier = $this->getFdResponse($conn);
144
145
        if (is_null($replier) || !$this->server->exist($conn)) {
146
            return false;
147
        }
148
149
        $replier->status($response->getStatusCode());
150
151
        $headers = $response->getHeaders();
152
        foreach ($headers as $name => $values) {
153
            $replier->header($name, implode(',', $values));
154
        }
155
156
        $replier->end((string)$response->getBody());
157
158
        return true;
159
    }
160
161
    /**
162
     * @param int $conn
163
     * @return bool
164
     */
165
    public function close(int $conn) : bool
166
    {
167
        return $this->server->close($conn) ? true : false;
168
    }
169
170
    /**
171
     * @param int $fd
172
     * @param SWHResponse $response
173
     * @return int
174
     */
175
    private function setFdResponse(int $fd, SWHResponse $response) : int
176
    {
177
        $this->fds[$fd] = $response;
178
        return $fd;
179
    }
180
181
    /**
182
     * @param int $fd
183
     * @return SWHResponse
184
     */
185
    private function getFdResponse(int $fd) : ?SWHResponse
186
    {
187
        if (isset($this->fds[$fd])) {
188
            $resp = $this->fds[$fd];
189
            unset($this->fds[$fd]);
190
            return $resp;
191
        } else {
192
            return null;
193
        }
194
    }
195
}
196