Tea.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. namespace AlibabaCloud\Tea;
  3. use AlibabaCloud\Tea\Exception\TeaError;
  4. use GuzzleHttp\Client;
  5. use GuzzleHttp\Exception\GuzzleException;
  6. use GuzzleHttp\HandlerStack;
  7. use GuzzleHttp\Middleware;
  8. use GuzzleHttp\Promise\PromiseInterface;
  9. use GuzzleHttp\TransferStats;
  10. use Psr\Http\Message\RequestInterface;
  11. use Psr\Http\Message\ResponseInterface;
  12. use Psr\Http\Message\UriInterface;
  13. /**
  14. * Class Tea.
  15. */
  16. class Tea
  17. {
  18. /**
  19. * @var array
  20. */
  21. private static $config = [];
  22. public static function config(array $config)
  23. {
  24. self::$config = $config;
  25. }
  26. /**
  27. * @throws GuzzleException
  28. *
  29. * @return Response
  30. */
  31. public static function send(Request $request, array $config = [])
  32. {
  33. if (method_exists($request, 'getPsrRequest')) {
  34. $request = $request->getPsrRequest();
  35. }
  36. $config['http_errors'] = false;
  37. $res = self::client()->send(
  38. $request,
  39. $config
  40. );
  41. return new Response($res);
  42. }
  43. /**
  44. * @return PromiseInterface
  45. */
  46. public static function sendAsync(RequestInterface $request, array $config = [])
  47. {
  48. if (method_exists($request, 'getPsrRequest')) {
  49. $request = $request->getPsrRequest();
  50. }
  51. $config['http_errors'] = false;
  52. return self::client()->sendAsync(
  53. $request,
  54. $config
  55. );
  56. }
  57. /**
  58. * @return Client
  59. */
  60. public static function client(array $config = [])
  61. {
  62. if (isset(self::$config['handler'])) {
  63. $stack = self::$config['handler'];
  64. } else {
  65. $stack = HandlerStack::create();
  66. $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) {
  67. return new Response($response);
  68. }));
  69. }
  70. self::$config['handler'] = $stack;
  71. if (!isset(self::$config['on_stats'])) {
  72. self::$config['on_stats'] = function (TransferStats $stats) {
  73. Response::$info = $stats->getHandlerStats();
  74. };
  75. }
  76. $new_config = Helper::merge([self::$config, $config]);
  77. return new Client($new_config);
  78. }
  79. /**
  80. * @param string $method
  81. * @param string|UriInterface $uri
  82. * @param array $options
  83. *
  84. * @throws GuzzleException
  85. *
  86. * @return ResponseInterface
  87. */
  88. public static function request($method, $uri, $options = [])
  89. {
  90. return self::client()->request($method, $uri, $options);
  91. }
  92. /**
  93. * @param string $method
  94. * @param string $uri
  95. * @param array $options
  96. *
  97. * @throws GuzzleException
  98. *
  99. * @return string
  100. */
  101. public static function string($method, $uri, $options = [])
  102. {
  103. return (string) self::client()->request($method, $uri, $options)
  104. ->getBody();
  105. }
  106. /**
  107. * @param string $method
  108. * @param string|UriInterface $uri
  109. * @param array $options
  110. *
  111. * @return PromiseInterface
  112. */
  113. public static function requestAsync($method, $uri, $options = [])
  114. {
  115. return self::client()->requestAsync($method, $uri, $options);
  116. }
  117. /**
  118. * @param string|UriInterface $uri
  119. * @param array $options
  120. *
  121. * @throws GuzzleException
  122. *
  123. * @return null|mixed
  124. */
  125. public static function getHeaders($uri, $options = [])
  126. {
  127. return self::request('HEAD', $uri, $options)->getHeaders();
  128. }
  129. /**
  130. * @param string|UriInterface $uri
  131. * @param string $key
  132. * @param null|mixed $default
  133. *
  134. * @throws GuzzleException
  135. *
  136. * @return null|mixed
  137. */
  138. public static function getHeader($uri, $key, $default = null)
  139. {
  140. $headers = self::getHeaders($uri);
  141. return isset($headers[$key][0]) ? $headers[$key][0] : $default;
  142. }
  143. /**
  144. * @param int $retryTimes
  145. * @param float $now
  146. *
  147. * @return bool
  148. */
  149. public static function allowRetry(array $runtime, $retryTimes, $now)
  150. {
  151. unset($now);
  152. if (empty($runtime) || !isset($runtime['maxAttempts'])) {
  153. return false;
  154. }
  155. $maxAttempts = $runtime['maxAttempts'];
  156. $retry = empty($maxAttempts) ? 0 : (int) $maxAttempts;
  157. return $retry >= $retryTimes;
  158. }
  159. /**
  160. * @param int $retryTimes
  161. *
  162. * @return int
  163. */
  164. public static function getBackoffTime(array $runtime, $retryTimes)
  165. {
  166. $backOffTime = 0;
  167. $policy = isset($runtime['policy']) ? $runtime['policy'] : '';
  168. if (empty($policy) || 'no' == $policy) {
  169. return $backOffTime;
  170. }
  171. $period = isset($runtime['period']) ? $runtime['period'] : '';
  172. if (null !== $period && '' !== $period) {
  173. $backOffTime = (int) $period;
  174. if ($backOffTime <= 0) {
  175. return $retryTimes;
  176. }
  177. }
  178. return $backOffTime;
  179. }
  180. public static function sleep($time)
  181. {
  182. sleep($time);
  183. }
  184. public static function isRetryable($retry, $retryTimes = 0)
  185. {
  186. if ($retry instanceof TeaError) {
  187. return true;
  188. }
  189. if (\is_array($retry)) {
  190. $max = isset($retry['maxAttempts']) ? (int) ($retry['maxAttempts']) : 3;
  191. return $retryTimes <= $max;
  192. }
  193. return false;
  194. }
  195. /**
  196. * @param mixed|Model[] ...$item
  197. *
  198. * @return mixed
  199. */
  200. public static function merge(...$item)
  201. {
  202. $tmp = [];
  203. $n = 0;
  204. foreach ($item as $i) {
  205. if (\is_object($i)) {
  206. if ($i instanceof Model) {
  207. $i = $i->toMap();
  208. } else {
  209. $i = json_decode(json_encode($i), true);
  210. }
  211. }
  212. if (null === $i) {
  213. continue;
  214. }
  215. if (\is_array($i)) {
  216. $tmp[$n++] = $i;
  217. }
  218. }
  219. if (count($tmp)) {
  220. return \call_user_func_array('array_merge', $tmp);
  221. }
  222. return [];
  223. }
  224. }