1 | <?php |
||||
2 | |||||
3 | namespace AlibabaCloud\Client\Request; |
||||
4 | |||||
5 | use AlibabaCloud\Client\AlibabaCloud; |
||||
6 | use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider; |
||||
7 | use AlibabaCloud\Client\Encode; |
||||
8 | use AlibabaCloud\Client\Exception\ClientException; |
||||
9 | use AlibabaCloud\Client\Exception\ServerException; |
||||
10 | use AlibabaCloud\Client\Filter\ApiFilter; |
||||
11 | use AlibabaCloud\Client\Filter\ClientFilter; |
||||
12 | use AlibabaCloud\Client\Filter\Filter; |
||||
13 | use AlibabaCloud\Client\Filter\HttpFilter; |
||||
14 | use AlibabaCloud\Client\Request\Traits\AcsTrait; |
||||
15 | use AlibabaCloud\Client\Request\Traits\ClientTrait; |
||||
16 | use AlibabaCloud\Client\Request\Traits\DeprecatedTrait; |
||||
17 | use AlibabaCloud\Client\Request\Traits\RetryTrait; |
||||
18 | use AlibabaCloud\Client\Result\Result; |
||||
19 | use AlibabaCloud\Client\SDK; |
||||
20 | use AlibabaCloud\Client\Traits\ArrayAccessTrait; |
||||
21 | use AlibabaCloud\Client\Traits\HttpTrait; |
||||
22 | use AlibabaCloud\Client\Traits\ObjectAccessTrait; |
||||
23 | use AlibabaCloud\Client\Traits\RegionTrait; |
||||
24 | use ArrayAccess; |
||||
25 | use Exception; |
||||
26 | use GuzzleHttp\Client; |
||||
27 | use GuzzleHttp\Exception\GuzzleException; |
||||
28 | use GuzzleHttp\HandlerStack; |
||||
29 | use GuzzleHttp\MessageFormatter; |
||||
30 | use GuzzleHttp\Middleware; |
||||
31 | use GuzzleHttp\Promise\PromiseInterface; |
||||
32 | use GuzzleHttp\Psr7\Uri; |
||||
33 | use Psr\Http\Message\ResponseInterface; |
||||
34 | |||||
35 | /** |
||||
36 | * Class Request |
||||
37 | * |
||||
38 | * @package AlibabaCloud\Client\Request |
||||
39 | * |
||||
40 | * @method string stringToSign() |
||||
41 | * @method string resolveParameter() |
||||
42 | */ |
||||
43 | abstract class Request implements ArrayAccess |
||||
44 | { |
||||
45 | use DeprecatedTrait; |
||||
46 | use HttpTrait; |
||||
47 | use RegionTrait; |
||||
48 | use ClientTrait; |
||||
49 | use AcsTrait; |
||||
50 | use ArrayAccessTrait; |
||||
51 | use ObjectAccessTrait; |
||||
52 | use RetryTrait; |
||||
53 | |||||
54 | /** |
||||
55 | * Request Connect Timeout |
||||
56 | */ |
||||
57 | const CONNECT_TIMEOUT = 5; |
||||
58 | |||||
59 | /** |
||||
60 | * Request Timeout |
||||
61 | */ |
||||
62 | const TIMEOUT = 10; |
||||
63 | |||||
64 | /** |
||||
65 | * @var string HTTP Method |
||||
66 | */ |
||||
67 | public $method = 'GET'; |
||||
68 | |||||
69 | /** |
||||
70 | * @var string |
||||
71 | */ |
||||
72 | public $format = 'JSON'; |
||||
73 | |||||
74 | /** |
||||
75 | * @var string HTTP Scheme |
||||
76 | */ |
||||
77 | protected $scheme = 'http'; |
||||
78 | |||||
79 | /** |
||||
80 | * @var string |
||||
81 | */ |
||||
82 | public $client; |
||||
83 | |||||
84 | /** |
||||
85 | * @var Uri |
||||
86 | */ |
||||
87 | public $uri; |
||||
88 | |||||
89 | /** |
||||
90 | * @var array The original parameters of the request. |
||||
91 | */ |
||||
92 | public $data = []; |
||||
93 | |||||
94 | /** |
||||
95 | * @var array |
||||
96 | */ |
||||
97 | private $userAgent = []; |
||||
98 | |||||
99 | /** |
||||
100 | * Request constructor. |
||||
101 | * |
||||
102 | * @param array $options |
||||
103 | * |
||||
104 | * @throws ClientException |
||||
105 | */ |
||||
106 | 199 | public function __construct(array $options = []) |
|||
107 | { |
||||
108 | 199 | $this->client = CredentialsProvider::getDefaultName(); |
|||
109 | 199 | $this->uri = new Uri(); |
|||
110 | 199 | $this->uri = $this->uri->withScheme($this->scheme); |
|||
111 | 199 | $this->options['http_errors'] = false; |
|||
112 | 199 | $this->options['connect_timeout'] = self::CONNECT_TIMEOUT; |
|||
113 | 199 | $this->options['timeout'] = self::TIMEOUT; |
|||
114 | |||||
115 | // Turn on debug mode based on environment variable. |
||||
116 | 199 | if (null !== \AlibabaCloud\Client\env('DEBUG') && strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') { |
|||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
117 | 101 | $this->options['debug'] = true; |
|||
118 | 101 | } |
|||
119 | |||||
120 | // Rewrite configuration if the user has a configuration. |
||||
121 | 199 | if ($options !== []) { |
|||
122 | 1 | $this->options($options); |
|||
123 | 1 | } |
|||
124 | 199 | } |
|||
125 | |||||
126 | /** |
||||
127 | * @param string $name |
||||
128 | * @param string $value |
||||
129 | * |
||||
130 | * @return $this |
||||
131 | * @throws ClientException |
||||
132 | */ |
||||
133 | 5 | public function appendUserAgent($name, $value) |
|||
134 | { |
||||
135 | 5 | $filter_name = Filter::name($name); |
|||
136 | |||||
137 | 3 | if (!UserAgent::isGuarded($filter_name)) { |
|||
138 | 3 | $this->userAgent[$filter_name] = Filter::value($value); |
|||
139 | 1 | } |
|||
140 | |||||
141 | 1 | return $this; |
|||
142 | } |
||||
143 | |||||
144 | /** |
||||
145 | * @param array $userAgent |
||||
146 | * |
||||
147 | * @return $this |
||||
148 | */ |
||||
149 | 2 | public function withUserAgent(array $userAgent) |
|||
150 | { |
||||
151 | 2 | $this->userAgent = UserAgent::clean($userAgent); |
|||
152 | |||||
153 | 2 | return $this; |
|||
154 | } |
||||
155 | |||||
156 | /** |
||||
157 | * Set Accept format. |
||||
158 | * |
||||
159 | * @param string $format |
||||
160 | * |
||||
161 | * @return $this |
||||
162 | * @throws ClientException |
||||
163 | */ |
||||
164 | 14 | public function format($format) |
|||
165 | { |
||||
166 | 14 | $this->format = ApiFilter::format($format); |
|||
167 | |||||
168 | 12 | return $this; |
|||
169 | } |
||||
170 | |||||
171 | /** |
||||
172 | * @param $contentType |
||||
173 | * |
||||
174 | * @return $this |
||||
175 | * @throws ClientException |
||||
176 | */ |
||||
177 | 1 | public function contentType($contentType) |
|||
178 | { |
||||
179 | 1 | $this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType); |
|||
180 | |||||
181 | 1 | return $this; |
|||
182 | 1 | } |
|||
183 | |||||
184 | /** |
||||
185 | * @param string $accept |
||||
186 | * |
||||
187 | * @return $this |
||||
188 | * @throws ClientException |
||||
189 | */ |
||||
190 | 2 | public function accept($accept) |
|||
191 | { |
||||
192 | 2 | $this->options['headers']['Accept'] = HttpFilter::accept($accept); |
|||
193 | |||||
194 | 2 | return $this; |
|||
195 | } |
||||
196 | |||||
197 | /** |
||||
198 | * Set the request body. |
||||
199 | * |
||||
200 | * @param string $body |
||||
201 | * |
||||
202 | * @return $this |
||||
203 | * @throws ClientException |
||||
204 | */ |
||||
205 | 5 | public function body($body) |
|||
206 | { |
||||
207 | 5 | $this->options['body'] = HttpFilter::body($body); |
|||
208 | |||||
209 | 3 | return $this; |
|||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * Set the json as body. |
||||
214 | * |
||||
215 | * @param array|object $content |
||||
216 | * |
||||
217 | * @return $this |
||||
218 | * @throws ClientException |
||||
219 | */ |
||||
220 | 3 | public function jsonBody($content) |
|||
221 | { |
||||
222 | 3 | if (!\is_array($content) && !\is_object($content)) { |
|||
223 | 1 | throw new ClientException( |
|||
224 | 1 | 'jsonBody only accepts an array or object', |
|||
225 | SDK::INVALID_ARGUMENT |
||||
226 | 1 | ); |
|||
227 | } |
||||
228 | |||||
229 | 2 | return $this->body(\json_encode($content)); |
|||
230 | } |
||||
231 | |||||
232 | /** |
||||
233 | * Set the request scheme. |
||||
234 | * |
||||
235 | * @param string $scheme |
||||
236 | * |
||||
237 | * @return $this |
||||
238 | * @throws ClientException |
||||
239 | */ |
||||
240 | 17 | public function scheme($scheme) |
|||
241 | { |
||||
242 | 17 | $this->scheme = HttpFilter::scheme($scheme); |
|||
243 | 15 | $this->uri = $this->uri->withScheme($scheme); |
|||
244 | |||||
245 | 15 | return $this; |
|||
246 | } |
||||
247 | |||||
248 | /** |
||||
249 | * Set the request host. |
||||
250 | * |
||||
251 | * @param string $host |
||||
252 | * |
||||
253 | * @return $this |
||||
254 | * @throws ClientException |
||||
255 | */ |
||||
256 | 28 | public function host($host) |
|||
257 | { |
||||
258 | 28 | $this->uri = $this->uri->withHost(HttpFilter::host($host)); |
|||
259 | |||||
260 | 26 | return $this; |
|||
261 | } |
||||
262 | |||||
263 | /** |
||||
264 | * @param string $method |
||||
265 | * |
||||
266 | * @return $this |
||||
267 | * @throws ClientException |
||||
268 | */ |
||||
269 | 54 | public function method($method) |
|||
270 | { |
||||
271 | 54 | $this->method = HttpFilter::method($method); |
|||
272 | |||||
273 | 52 | return $this; |
|||
274 | } |
||||
275 | |||||
276 | /** |
||||
277 | * @param string $clientName |
||||
278 | * |
||||
279 | * @return $this |
||||
280 | * @throws ClientException |
||||
281 | */ |
||||
282 | 67 | public function client($clientName) |
|||
283 | { |
||||
284 | 67 | $this->client = ClientFilter::clientName($clientName); |
|||
285 | |||||
286 | 65 | return $this; |
|||
287 | } |
||||
288 | |||||
289 | /** |
||||
290 | * @return bool |
||||
291 | * @throws ClientException |
||||
292 | */ |
||||
293 | 1 | public function isDebug() |
|||
294 | { |
||||
295 | 1 | if (isset($this->options['debug'])) { |
|||
296 | 1 | return $this->options['debug'] === true; |
|||
297 | } |
||||
298 | |||||
299 | 1 | if (isset($this->httpClient()->options['debug'])) { |
|||
300 | 1 | return $this->httpClient()->options['debug'] === true; |
|||
301 | } |
||||
302 | |||||
303 | 1 | return false; |
|||
304 | } |
||||
305 | |||||
306 | /** |
||||
307 | * @throws ClientException |
||||
308 | * @throws ServerException |
||||
309 | */ |
||||
310 | 71 | public function resolveOption() |
|||
311 | { |
||||
312 | 71 | $this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent); |
|||
313 | |||||
314 | 71 | $this->cleanQuery(); |
|||
315 | 71 | $this->cleanFormParams(); |
|||
316 | 71 | $this->resolveHost(); |
|||
317 | 68 | $this->resolveParameter(); |
|||
318 | |||||
319 | 65 | if (isset($this->options['form_params'])) { |
|||
320 | 32 | if (function_exists('\GuzzleHttp\Psr7\parse_query')) { |
|||
321 | 32 | $this->options['form_params'] = \GuzzleHttp\Psr7\parse_query( |
|||
0 ignored issues
–
show
The function
GuzzleHttp\Psr7\parse_query() has been deprecated: parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
322 | 32 | Encode::create($this->options['form_params'])->toString() |
|||
323 | 32 | ); |
|||
324 | } else { |
||||
325 | 65 | $this->options['form_params'] = \GuzzleHttp\Psr7\Query::parse( |
|||
326 | 65 | Encode::create($this->options['form_params'])->toString() |
|||
327 | ); |
||||
328 | } |
||||
329 | } |
||||
330 | |||||
331 | $this->mergeOptionsIntoClient(); |
||||
332 | } |
||||
333 | 69 | ||||
334 | /** |
||||
335 | 69 | * @return Result |
|||
336 | 63 | * @throws ClientException |
|||
337 | * @throws ServerException |
||||
338 | 56 | */ |
|||
339 | 2 | public function request() |
|||
340 | { |
||||
341 | $this->resolveOption(); |
||||
342 | 56 | $result = $this->response(); |
|||
343 | 22 | ||||
344 | if ($this->shouldServerRetry($result)) { |
||||
345 | return $this->request(); |
||||
346 | 35 | } |
|||
347 | |||||
348 | if (!$result->isSuccess()) { |
||||
0 ignored issues
–
show
The method
isSuccess() does not exist on Psr\Http\Message\ResponseInterface . It seems like you code against a sub-type of Psr\Http\Message\ResponseInterface such as AlibabaCloud\Client\Result\Result .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
349 | throw new ServerException($result); |
||||
350 | } |
||||
351 | |||||
352 | return $result; |
||||
353 | 2 | } |
|||
354 | |||||
355 | 2 | /*** |
|||
356 | * @return PromiseInterface |
||||
357 | 2 | * @throws Exception |
|||
358 | 2 | */ |
|||
359 | 2 | public function requestAsync() |
|||
360 | 2 | { |
|||
361 | 2 | $this->resolveOption(); |
|||
362 | |||||
363 | return self::createClient($this)->requestAsync( |
||||
364 | $this->method, |
||||
365 | (string)$this->uri, |
||||
366 | $this->options |
||||
367 | ); |
||||
368 | } |
||||
369 | |||||
370 | 75 | /** |
|||
371 | * @param Request $request |
||||
372 | 75 | * |
|||
373 | 22 | * @return Client |
|||
374 | 22 | * @throws Exception |
|||
375 | 53 | */ |
|||
376 | public static function createClient(Request $request = null) |
||||
377 | { |
||||
378 | 75 | if (AlibabaCloud::hasMock()) { |
|||
379 | 40 | $stack = HandlerStack::create(AlibabaCloud::getMock()); |
|||
380 | 40 | } else { |
|||
381 | $stack = HandlerStack::create(); |
||||
382 | 75 | } |
|||
383 | 2 | ||||
384 | 2 | if (AlibabaCloud::isRememberHistory()) { |
|||
385 | 2 | $stack->push(Middleware::history(AlibabaCloud::referenceHistory())); |
|||
386 | 2 | } |
|||
387 | 2 | ||||
388 | if (AlibabaCloud::getLogger()) { |
||||
389 | 75 | $stack->push(Middleware::log( |
|||
390 | 61 | AlibabaCloud::getLogger(), |
|||
391 | 75 | new MessageFormatter(AlibabaCloud::getLogFormat()) |
|||
392 | )); |
||||
393 | 75 | } |
|||
394 | |||||
395 | 75 | $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) { |
|||
396 | return new Result($response, $request); |
||||
397 | })); |
||||
398 | |||||
399 | self::$config['handler'] = $stack; |
||||
400 | |||||
401 | return new Client(self::$config); |
||||
402 | 63 | } |
|||
403 | |||||
404 | /** |
||||
405 | 63 | * @throws ClientException |
|||
406 | 63 | * @throws Exception |
|||
407 | 63 | */ |
|||
408 | 63 | private function response() |
|||
409 | 63 | { |
|||
410 | 8 | try { |
|||
411 | 7 | return self::createClient($this)->request( |
|||
412 | 2 | $this->method, |
|||
413 | (string)$this->uri, |
||||
414 | 7 | $this->options |
|||
415 | 7 | ); |
|||
416 | 7 | } catch (GuzzleException $exception) { |
|||
417 | if ($this->shouldClientRetry($exception)) { |
||||
418 | 7 | return $this->response(); |
|||
419 | } |
||||
420 | throw new ClientException( |
||||
421 | $exception->getMessage(), |
||||
422 | SDK::SERVER_UNREACHABLE, |
||||
423 | $exception |
||||
424 | ); |
||||
425 | } |
||||
426 | } |
||||
427 | |||||
428 | /** |
||||
429 | * Remove redundant Query |
||||
430 | * |
||||
431 | * @codeCoverageIgnore |
||||
432 | */ |
||||
433 | private function cleanQuery() |
||||
434 | { |
||||
435 | if (isset($this->options['query']) && $this->options['query'] === []) { |
||||
436 | unset($this->options['query']); |
||||
437 | } |
||||
438 | } |
||||
439 | |||||
440 | /** |
||||
441 | * Remove redundant Headers |
||||
442 | * |
||||
443 | * @codeCoverageIgnore |
||||
444 | */ |
||||
445 | private function cleanFormParams() |
||||
446 | { |
||||
447 | if (isset($this->options['form_params']) && $this->options['form_params'] === []) { |
||||
448 | unset($this->options['form_params']); |
||||
449 | } |
||||
450 | } |
||||
451 | } |
||||
452 |