RpcRequest.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. namespace AlibabaCloud\Client\Request;
  3. use Exception;
  4. use RuntimeException;
  5. use AlibabaCloud\Client\Support\Sign;
  6. use AlibabaCloud\Client\Support\Arrays;
  7. use AlibabaCloud\Client\Credentials\StsCredential;
  8. use AlibabaCloud\Client\Exception\ClientException;
  9. use AlibabaCloud\Client\Exception\ServerException;
  10. use AlibabaCloud\Client\Credentials\BearerTokenCredential;
  11. /**
  12. * RESTful RPC Request.
  13. *
  14. * @package AlibabaCloud\Client\Request
  15. */
  16. class RpcRequest extends Request
  17. {
  18. /**
  19. * @var string
  20. */
  21. private $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
  22. /**
  23. * Resolve request parameter.
  24. *
  25. * @throws ClientException
  26. */
  27. public function resolveParameter()
  28. {
  29. $this->resolveBoolInParameters();
  30. $this->resolveCommonParameters();
  31. $this->repositionParameters();
  32. }
  33. /**
  34. * Convert a Boolean value to a string
  35. */
  36. private function resolveBoolInParameters()
  37. {
  38. if (isset($this->options['query'])) {
  39. $this->options['query'] = array_map(
  40. static function ($value) {
  41. return self::boolToString($value);
  42. },
  43. $this->options['query']
  44. );
  45. }
  46. }
  47. /**
  48. * Convert a Boolean value to a string.
  49. *
  50. * @param bool|string $value
  51. *
  52. * @return string
  53. */
  54. public static function boolToString($value)
  55. {
  56. if (is_bool($value)) {
  57. return $value ? 'true' : 'false';
  58. }
  59. return $value;
  60. }
  61. /**
  62. * Resolve Common Parameters.
  63. *
  64. * @throws ClientException
  65. * @throws Exception
  66. */
  67. private function resolveCommonParameters()
  68. {
  69. $signature = $this->httpClient()->getSignature();
  70. $this->options['query']['RegionId'] = $this->realRegionId();
  71. $this->options['query']['Format'] = $this->format;
  72. $this->options['query']['SignatureMethod'] = $signature->getMethod();
  73. $this->options['query']['SignatureVersion'] = $signature->getVersion();
  74. $this->options['query']['SignatureNonce'] = Sign::uuid($this->product . $this->action);
  75. $this->options['query']['Timestamp'] = gmdate($this->dateTimeFormat);
  76. $this->options['query']['Action'] = $this->action;
  77. if ($this->credential()->getAccessKeyId()) {
  78. $this->options['query']['AccessKeyId'] = $this->credential()->getAccessKeyId();
  79. }
  80. if ($signature->getType()) {
  81. $this->options['query']['SignatureType'] = $signature->getType();
  82. }
  83. if (!isset($this->options['query']['Version'])) {
  84. $this->options['query']['Version'] = $this->version;
  85. }
  86. $this->resolveSecurityToken();
  87. $this->resolveBearerToken();
  88. $this->options['query']['Signature'] = $this->signature();
  89. }
  90. /**
  91. * @throws ClientException
  92. * @throws ServerException
  93. */
  94. private function resolveSecurityToken()
  95. {
  96. if (!$this->credential() instanceof StsCredential) {
  97. return;
  98. }
  99. if (!$this->credential()->getSecurityToken()) {
  100. return;
  101. }
  102. $this->options['query']['SecurityToken'] = $this->credential()->getSecurityToken();
  103. }
  104. /**
  105. * @throws ClientException
  106. * @throws ServerException
  107. */
  108. private function resolveBearerToken()
  109. {
  110. if ($this->credential() instanceof BearerTokenCredential) {
  111. $this->options['query']['BearerToken'] = $this->credential()->getBearerToken();
  112. }
  113. }
  114. /**
  115. * Sign the parameters.
  116. *
  117. * @return mixed
  118. * @throws ClientException
  119. * @throws ServerException
  120. */
  121. private function signature()
  122. {
  123. return $this->httpClient()
  124. ->getSignature()
  125. ->sign(
  126. $this->stringToSign(),
  127. $this->credential()->getAccessKeySecret() . '&'
  128. );
  129. }
  130. /**
  131. * @return string
  132. */
  133. public function stringToSign()
  134. {
  135. $query = isset($this->options['query']) ? $this->options['query'] : [];
  136. $form_params = isset($this->options['form_params']) ? $this->options['form_params'] : [];
  137. $parameters = Arrays::merge([$query, $form_params]);
  138. return Sign::rpcString($this->method, $parameters);
  139. }
  140. /**
  141. * Adjust parameter position
  142. */
  143. private function repositionParameters()
  144. {
  145. if ($this->method === 'POST' || $this->method === 'PUT') {
  146. foreach ($this->options['query'] as $api_key => $api_value) {
  147. $this->options['form_params'][$api_key] = $api_value;
  148. }
  149. unset($this->options['query']);
  150. }
  151. }
  152. /**
  153. * Magic method for set or get request parameters.
  154. *
  155. * @param string $name
  156. * @param mixed $arguments
  157. *
  158. * @return $this
  159. */
  160. public function __call($name, $arguments)
  161. {
  162. if (strncmp($name, 'get', 3) === 0) {
  163. $parameter_name = \mb_strcut($name, 3);
  164. return $this->__get($parameter_name);
  165. }
  166. if (strncmp($name, 'with', 4) === 0) {
  167. $parameter_name = \mb_strcut($name, 4);
  168. $this->__set($parameter_name, $arguments[0]);
  169. $this->options['query'][$parameter_name] = $arguments[0];
  170. return $this;
  171. }
  172. if (strncmp($name, 'set', 3) === 0) {
  173. $parameter_name = \mb_strcut($name, 3);
  174. $with_method = "with$parameter_name";
  175. throw new RuntimeException("Please use $with_method instead of $name");
  176. }
  177. throw new RuntimeException('Call to undefined method ' . __CLASS__ . '::' . $name . '()');
  178. }
  179. }