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 (strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') { |
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 |
|
$this->options['form_params'] = \GuzzleHttp\Psr7\parse_query( |
|
|
|
|
321
|
32 |
|
Encode::create($this->options['form_params'])->toString() |
322
|
32 |
|
); |
323
|
32 |
|
} |
324
|
|
|
|
325
|
65 |
|
$this->mergeOptionsIntoClient(); |
326
|
65 |
|
} |
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* @return Result |
330
|
|
|
* @throws ClientException |
331
|
|
|
* @throws ServerException |
332
|
|
|
*/ |
333
|
69 |
|
public function request() |
334
|
|
|
{ |
335
|
69 |
|
$this->resolveOption(); |
336
|
63 |
|
$result = $this->response(); |
337
|
|
|
|
338
|
56 |
|
if ($this->shouldServerRetry($result)) { |
339
|
2 |
|
return $this->request(); |
340
|
|
|
} |
341
|
|
|
|
342
|
56 |
|
if (!$result->isSuccess()) { |
|
|
|
|
343
|
22 |
|
throw new ServerException($result); |
344
|
|
|
} |
345
|
|
|
|
346
|
35 |
|
return $result; |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
/*** |
350
|
|
|
* @return PromiseInterface |
351
|
|
|
* @throws Exception |
352
|
|
|
*/ |
353
|
2 |
|
public function requestAsync() |
354
|
|
|
{ |
355
|
2 |
|
$this->resolveOption(); |
356
|
|
|
|
357
|
2 |
|
return self::createClient($this)->requestAsync( |
358
|
2 |
|
$this->method, |
359
|
2 |
|
(string)$this->uri, |
360
|
2 |
|
$this->options |
361
|
2 |
|
); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* @param Request $request |
366
|
|
|
* |
367
|
|
|
* @return Client |
368
|
|
|
* @throws Exception |
369
|
|
|
*/ |
370
|
75 |
|
public static function createClient(Request $request = null) |
371
|
|
|
{ |
372
|
75 |
|
if (AlibabaCloud::hasMock()) { |
373
|
22 |
|
$stack = HandlerStack::create(AlibabaCloud::getMock()); |
374
|
22 |
|
} else { |
375
|
53 |
|
$stack = HandlerStack::create(); |
376
|
|
|
} |
377
|
|
|
|
378
|
75 |
|
if (AlibabaCloud::isRememberHistory()) { |
379
|
40 |
|
$stack->push(Middleware::history(AlibabaCloud::referenceHistory())); |
380
|
40 |
|
} |
381
|
|
|
|
382
|
75 |
|
if (AlibabaCloud::getLogger()) { |
383
|
2 |
|
$stack->push(Middleware::log( |
384
|
2 |
|
AlibabaCloud::getLogger(), |
385
|
2 |
|
new MessageFormatter(AlibabaCloud::getLogFormat()) |
386
|
2 |
|
)); |
387
|
2 |
|
} |
388
|
|
|
|
389
|
75 |
|
$stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) { |
390
|
61 |
|
return new Result($response, $request); |
391
|
75 |
|
})); |
392
|
|
|
|
393
|
75 |
|
self::$config['handler'] = $stack; |
394
|
|
|
|
395
|
75 |
|
return new Client(self::$config); |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
/** |
399
|
|
|
* @throws ClientException |
400
|
|
|
* @throws Exception |
401
|
|
|
*/ |
402
|
63 |
|
private function response() |
403
|
|
|
{ |
404
|
|
|
try { |
405
|
63 |
|
return self::createClient($this)->request( |
406
|
63 |
|
$this->method, |
407
|
63 |
|
(string)$this->uri, |
408
|
63 |
|
$this->options |
409
|
63 |
|
); |
410
|
8 |
|
} catch (GuzzleException $exception) { |
411
|
7 |
|
if ($this->shouldClientRetry($exception)) { |
412
|
2 |
|
return $this->response(); |
413
|
|
|
} |
414
|
7 |
|
throw new ClientException( |
415
|
7 |
|
$exception->getMessage(), |
416
|
7 |
|
SDK::SERVER_UNREACHABLE, |
417
|
|
|
$exception |
418
|
7 |
|
); |
419
|
|
|
} |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* Remove redundant Query |
424
|
|
|
* |
425
|
|
|
* @codeCoverageIgnore |
426
|
|
|
*/ |
427
|
|
|
private function cleanQuery() |
428
|
|
|
{ |
429
|
|
|
if (isset($this->options['query']) && $this->options['query'] === []) { |
430
|
|
|
unset($this->options['query']); |
431
|
|
|
} |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
/** |
435
|
|
|
* Remove redundant Headers |
436
|
|
|
* |
437
|
|
|
* @codeCoverageIgnore |
438
|
|
|
*/ |
439
|
|
|
private function cleanFormParams() |
440
|
|
|
{ |
441
|
|
|
if (isset($this->options['form_params']) && $this->options['form_params'] === []) { |
442
|
|
|
unset($this->options['form_params']); |
443
|
|
|
} |
444
|
|
|
} |
445
|
|
|
} |
446
|
|
|
|
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.