BaseClient.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <?php
  2. require_once(XASSET_PATH . 'auth/HttpUtils.php');
  3. abstract class BaseClient {
  4. // 请求默认超时设置
  5. const ReqConnTimeoutMs = 1000;
  6. const ReqTimeoutMs = 3000;
  7. // 错误码
  8. const ClientErrnoParamErr = 40001;
  9. const ClientErrnoCurlErr = 3004;
  10. const ClientErrnoRespErr = 3005;
  11. // 请求服务重试次数
  12. const RequestRetryTimes = 3;
  13. private $errCode = 0;
  14. private $errMsg = "";
  15. private $isHttps = false;
  16. private $host = "";
  17. private $signer;
  18. private $credentials;
  19. private $userAgent;
  20. private $connTimeout;
  21. private $rwTimeout;
  22. /**
  23. * BaseClient constructor.
  24. * @param $xassetConfig
  25. */
  26. public function __construct($xassetConfig) {
  27. $this->host = $xassetConfig->endPoint;
  28. $this->signer = $xassetConfig->signer;
  29. $this->credentials = $xassetConfig->credentials;
  30. $this->userAgent = $xassetConfig->userAgent;
  31. $this->connTimeout = $xassetConfig->connTimeout > 0 ? $xassetConfig->connTimeout : BaseClient::ReqConnTimeoutMs;
  32. $this->rwTimeout = $xassetConfig->rwTimeout > 0 ? $xassetConfig->rwTimeout : BaseClient::ReqTimeoutMs;
  33. $this->isHttps = $this->setHttps();
  34. }
  35. /**
  36. * @param
  37. * @return bool
  38. */
  39. private function setHttps() {
  40. $pos = strpos(strtolower($this->host), "https");
  41. if ($pos === false) {
  42. return false;
  43. }
  44. return true;
  45. }
  46. public function isHttps() {
  47. return $this->isHttps;
  48. }
  49. /**
  50. * @param
  51. * @return
  52. **/
  53. public function getErrCode() {
  54. return $this->errCode;
  55. }
  56. /**
  57. * @param
  58. * @return
  59. **/
  60. public function getErrMsg() {
  61. return $this->errMsg;
  62. }
  63. /**
  64. * @param
  65. * @return
  66. **/
  67. protected function setError($errCode, $errMsg) {
  68. $this->errCode = $errCode;
  69. $this->errMsg = $errMsg;
  70. }
  71. /**
  72. * @param
  73. * @return
  74. **/
  75. protected function cleanError() {
  76. $this->errCode = 0;
  77. $this->errMsg = "";
  78. }
  79. /**
  80. * @param $uri
  81. * @param $param
  82. * @param array $body
  83. * @return array|bool
  84. */
  85. protected function doRequestRetry($uri, $param, $body = array())
  86. {
  87. $res = false;
  88. $reqTimes = 0;
  89. while ($reqTimes < self::RequestRetryTimes) {
  90. $res = $this->doRequest($uri, $param, $body);
  91. if (!empty($res)) {
  92. break;
  93. }
  94. $reqTimes++;
  95. }
  96. if (!empty($res)) {
  97. $res['req_times'] = $reqTimes;
  98. }
  99. return $res;
  100. }
  101. /**
  102. * @param $uri
  103. * @param array $param
  104. * @param array $body
  105. * @return array|bool
  106. */
  107. protected function doRequest($uri, $param = array(), $body = array())
  108. {
  109. $time = new DateTime();
  110. $arrUrl = parse_url($this->host);
  111. $header = array(
  112. "Host" => $arrUrl['host'],
  113. "Content-Type" => "application/x-www-form-urlencoded;charset=utf-8",
  114. "Timestamp" => $time->getTimestamp(),
  115. "User-Agent" => $this->userAgent,
  116. );
  117. $option = array(
  118. "timestamp" => $time,
  119. "headersToSign" => array("host"),
  120. );
  121. $method = "GET";
  122. if (!empty($body)) {
  123. $method = "POST";
  124. }
  125. $encodedParam = $this->formatQueryString($param);
  126. $sign = $this->signer->sign($this->credentials, $method, $uri, $header, $encodedParam, $option);
  127. $header["Authorization"] = $sign;
  128. if (!empty($param)) {
  129. $uri .= "?" . $this->formatBody($param);
  130. }
  131. $res = $this->doRequestByHostRaw($this->host, $uri, $body, $header, $method);
  132. if (empty($res)) {
  133. return $res;
  134. }
  135. $url = $res['url'];
  136. $respRes = json_decode($res["response"], true);
  137. if (empty($respRes) || !isset($respRes['errno'])) {
  138. $error = sprintf("response error.url:%s response:%s", $url, $res['response']);
  139. $this->setError(BaseClient::ClientErrnoRespErr, $error);
  140. return false;
  141. }
  142. return array(
  143. 'url' => $url,
  144. 'response' => $respRes,
  145. );
  146. }
  147. /**
  148. * @param
  149. * @return array|bool
  150. **/
  151. protected function doRequestByHostRaw($host, $uri, $body, $header = null, $method='POST') {
  152. $url = $this->formatUrl($host, $uri);
  153. $curlRes = $this->curl_exec($url, $body, $header, $method);
  154. if ($curlRes["result"] == false) {
  155. $error = sprintf("curl server fail.url:%s curl_info:%s", $url, json_encode($curlRes));
  156. $this->setError(BaseClient::ClientErrnoCurlErr, $error);
  157. return false;
  158. }
  159. return array(
  160. 'url' => $url,
  161. 'response' => $curlRes['response'],
  162. );
  163. }
  164. /**
  165. * @param
  166. * @return
  167. **/
  168. protected function curl_exec($url, $body, $header = null, $method = 'POST') {
  169. $res = array(
  170. "result" => true,
  171. "errno" => 0,
  172. "error" => "",
  173. "http_code" => 200,
  174. "response" => "",
  175. );
  176. $ch = curl_init();
  177. curl_setopt($ch, CURLOPT_URL, $url);
  178. if ($method == 'POST') {
  179. curl_setopt($ch, CURLOPT_POST, true);
  180. curl_setopt($ch, CURLOPT_POSTFIELDS, $this->formatBody($body));
  181. }
  182. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  183. curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
  184. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connTimeout);
  185. curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->rwTimeout);
  186. if (is_array($header) && !empty($header)) {
  187. $headerArr = array();
  188. foreach ($header as $k => $v) {
  189. $headerArr[] = sprintf("%s: %s", $k, $v);
  190. }
  191. curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArr);
  192. }
  193. if ($this->isHttps()) {
  194. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  195. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  196. }
  197. $curlRet = curl_exec($ch);
  198. if(empty($curlRet)) {
  199. $res["result"] = false;
  200. $res["errno"] = curl_errno($ch);
  201. $res["error"] = curl_error($ch);
  202. $infos = curl_getinfo($ch);
  203. $res["http_code"] = $infos["http_code"];
  204. curl_close($ch);
  205. return $res;
  206. }
  207. curl_close($ch);
  208. $res["response"] = $curlRet;
  209. return $res;
  210. }
  211. /**
  212. * @param string $host
  213. * @param string $uri
  214. * @return string
  215. */
  216. protected function formatUrl($host, $uri) {
  217. return sprintf("%s%s", $host, $uri);
  218. }
  219. /**
  220. * 格式化 Body
  221. * @param $parameters
  222. * @return string
  223. */
  224. protected function formatBody($parameters) {
  225. $parameterStrings = array();
  226. foreach ($parameters as $k => $v) {
  227. $parameterStrings[] = HttpUtils::urlEncode($k)
  228. . '=' . HttpUtils::urlEncode((string) $v);
  229. }
  230. return implode('&', $parameterStrings);
  231. }
  232. /**
  233. * @param $account
  234. * @return bool
  235. */
  236. public static function isValidAccount($account) {
  237. if (!isset($account['address']) || !isset($account['private_key']) || !isset($account['public_key'])) {
  238. return false;
  239. }
  240. if (empty($account['address']) || empty($account['private_key']) || empty($account['public_key'])) {
  241. return false;
  242. }
  243. return true;
  244. }
  245. /**
  246. * 格式化 QueryString
  247. * @param array $parameters
  248. * @return array
  249. */
  250. private function formatQueryString($parameters) {
  251. $parameterArr = array();
  252. foreach ($parameters as $k => $v) {
  253. $parameterArr[HttpUtils::urlEncode($k)] = HttpUtils::urlEncode((string) $v);
  254. }
  255. return $parameterArr;
  256. }
  257. }