1 | <?php |
||||
2 | /** |
||||
3 | * HTTP client by swoole |
||||
4 | * User: moyo |
||||
5 | * Date: 12/09/2017 |
||||
6 | * Time: 3:07 PM |
||||
7 | */ |
||||
8 | |||||
9 | namespace Carno\HTTP\Powered\Swoole; |
||||
10 | |||||
11 | use function Carno\Coroutine\await; |
||||
12 | use Carno\HTTP\Contracts\Powered\Client as API; |
||||
13 | use Carno\HTTP\Exception\RequestTimeoutException; |
||||
14 | use Carno\HTTP\Options; |
||||
15 | use Carno\HTTP\Powered\Swoole\Chips\Http; |
||||
16 | use Carno\HTTP\Powered\Swoole\Chips\Socket; |
||||
17 | use Carno\HTTP\Powered\Swoole\Chips\Throws; |
||||
18 | use Carno\HTTP\Standard\Helper; |
||||
19 | use Carno\Net\Address; |
||||
20 | use Carno\Pool\Managed; |
||||
21 | use Carno\Pool\Poolable; |
||||
22 | use Carno\Promise\Promise; |
||||
23 | use Carno\Promise\Promised; |
||||
24 | use Psr\Http\Message\RequestInterface as Request; |
||||
25 | use Swoole\Http\Client as SWHClient; |
||||
0 ignored issues
–
show
|
|||||
26 | |||||
27 | class Client implements API, Poolable |
||||
28 | { |
||||
29 | use Helper, Managed; |
||||
30 | use Http, Socket, Throws; |
||||
0 ignored issues
–
show
|
|||||
31 | |||||
32 | /** |
||||
33 | * @var bool |
||||
34 | */ |
||||
35 | private $keepalive = false; |
||||
36 | |||||
37 | /** |
||||
38 | * @var Address |
||||
39 | */ |
||||
40 | private $connect = null; |
||||
41 | |||||
42 | /** |
||||
43 | * @var bool |
||||
44 | */ |
||||
45 | private $closing = false; |
||||
46 | |||||
47 | /** |
||||
48 | * @var SWHClient |
||||
49 | */ |
||||
50 | private $http = null; |
||||
51 | |||||
52 | /** |
||||
53 | * Client constructor. |
||||
54 | * @param Address $connect |
||||
55 | * @param bool $keepalive |
||||
56 | */ |
||||
57 | public function __construct(Address $connect, bool $keepalive = false) |
||||
58 | { |
||||
59 | $this->connect = $connect; |
||||
60 | $this->keepalive = $keepalive; |
||||
61 | } |
||||
62 | |||||
63 | /** |
||||
64 | * @param Request $request |
||||
65 | * @param Options $options |
||||
66 | */ |
||||
67 | private function initialize(Request $request, Options $options) : void |
||||
68 | { |
||||
69 | $this->http = new SWHClient( |
||||
70 | $this->connect->host(), |
||||
71 | $this->connect->port(), |
||||
72 | in_array($scheme = $request->getUri()->getScheme(), ['https', 'wss']) |
||||
73 | ); |
||||
74 | |||||
75 | $this->http->set([ |
||||
76 | 'open_tcp_nodelay' => true, |
||||
77 | 'keep_alive' => $this->keepalive || $socket = in_array($scheme, ['ws', 'wss']), |
||||
78 | ]); |
||||
79 | |||||
80 | ($socket ?? null) && $this->http->set(['websocket_mask' => true]); |
||||
81 | |||||
82 | if ($options->hasProxy()) { |
||||
83 | $px = $options->getProxy(); |
||||
84 | $pxc = [ |
||||
85 | 'http_proxy_host' => $px['host'], |
||||
86 | 'http_proxy_port' => $px['port'], |
||||
87 | ]; |
||||
88 | $px['user'] && $pxc['http_proxy_user'] = $px['user']; |
||||
89 | $px['pass'] && $pxc['http_proxy_password'] = $px['pass']; |
||||
90 | $this->http->set($pxc); |
||||
91 | } |
||||
92 | |||||
93 | $this->http->on('connect', function () { |
||||
94 | $this->http->on('error', [$this, 'failure']); |
||||
95 | $this->http->on('close', [$this, 'closing']); |
||||
96 | }); |
||||
97 | } |
||||
98 | |||||
99 | /** |
||||
100 | * @param string $ev |
||||
101 | */ |
||||
102 | private function finalize(string $ev) : void |
||||
0 ignored issues
–
show
The parameter
$ev is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
103 | { |
||||
104 | if (isset($this->http)) { |
||||
105 | unset($this->http); |
||||
106 | $this->disconnect(); |
||||
107 | } |
||||
108 | } |
||||
109 | |||||
110 | /** |
||||
111 | */ |
||||
112 | private function disconnect() : void |
||||
113 | { |
||||
114 | $this->closed()->pended() && $this->closed()->resolve(); |
||||
115 | } |
||||
116 | |||||
117 | /** |
||||
118 | * @return Promised |
||||
119 | */ |
||||
120 | public function connect() : Promised |
||||
121 | { |
||||
122 | return Promise::resolved(); |
||||
123 | } |
||||
124 | |||||
125 | /** |
||||
126 | * @return Promised |
||||
127 | */ |
||||
128 | public function heartbeat() : Promised |
||||
129 | { |
||||
130 | return Promise::resolved(); |
||||
131 | } |
||||
132 | |||||
133 | /** |
||||
134 | * @return Promised |
||||
135 | */ |
||||
136 | public function close() : Promised |
||||
137 | { |
||||
138 | if ($this->closing) { |
||||
139 | goto CLOSED_STA; |
||||
140 | } |
||||
141 | |||||
142 | $this->closing = true; |
||||
143 | |||||
144 | if (isset($this->http) && $this->http->isConnected()) { |
||||
145 | $this->http->close(); |
||||
146 | } else { |
||||
147 | $this->disconnect(); |
||||
148 | } |
||||
149 | |||||
150 | CLOSED_STA: |
||||
151 | |||||
152 | return $this->closed(); |
||||
153 | } |
||||
154 | |||||
155 | /** |
||||
156 | * @param SWHClient $c |
||||
157 | */ |
||||
158 | public function failure(SWHClient $c = null) : void |
||||
0 ignored issues
–
show
The parameter
$c is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
159 | { |
||||
160 | $this->finalize('error'); |
||||
161 | } |
||||
162 | |||||
163 | /** |
||||
164 | * @param SWHClient $c |
||||
165 | */ |
||||
166 | public function closing(SWHClient $c = null) : void |
||||
0 ignored issues
–
show
The parameter
$c is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
167 | { |
||||
168 | $this->finalize('close'); |
||||
169 | } |
||||
170 | |||||
171 | /** |
||||
172 | * @param Request $request |
||||
173 | * @param Options $options |
||||
174 | * @return Promised |
||||
175 | */ |
||||
176 | public function execute(Request $request, Options $options) : Promised |
||||
177 | { |
||||
178 | if (is_null($this->http)) { |
||||
179 | $this->initialize($request, $options); |
||||
180 | } |
||||
181 | |||||
182 | // config init --> |
||||
183 | |||||
184 | $this->http->set(['timeout' => $options->ttOverall > 0 ? round($options->ttOverall / 1000, 3) : -1]); |
||||
185 | |||||
186 | // host filter --> |
||||
187 | |||||
188 | if ($request->hasHeader('Host') && filter_var($request->getHeaderLine('Host'), FILTER_VALIDATE_IP)) { |
||||
189 | $request->withoutHeader('Host'); |
||||
190 | } |
||||
191 | |||||
192 | // keepalive parser --> |
||||
193 | |||||
194 | if (!$this->keepalive && |
||||
195 | (!$request->hasHeader('Connection') || |
||||
196 | ($request->hasHeader('Connection') && |
||||
197 | $request->getHeaderLine('Connection') !== 'close' |
||||
198 | ) |
||||
199 | ) |
||||
200 | ) { |
||||
201 | $request->withHeader('Connection', 'close'); |
||||
202 | } |
||||
203 | |||||
204 | // set headers --> |
||||
205 | |||||
206 | $this->http->setHeaders($this->getHeaderLines($request)); |
||||
207 | |||||
208 | // programme init --> |
||||
209 | |||||
210 | list($executor, $receiver) = |
||||
211 | $request->getMethod() === 'UPGRADE' |
||||
212 | ? $this->socket($request) |
||||
213 | : $this->http($request) |
||||
214 | ; |
||||
215 | |||||
216 | // executing --> |
||||
217 | |||||
218 | return await($executor, $receiver, $options->ttOverall, RequestTimeoutException::class, $request->getUri()); |
||||
219 | } |
||||
220 | } |
||||
221 |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths