Http.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. namespace JPush;
  3. use JPush\Exceptions\APIConnectionException;
  4. use JPush\Exceptions\APIRequestException;
  5. final class Http {
  6. public static function get($client, $url) {
  7. $response = self::sendRequest($client, $url, Config::HTTP_GET, $body=null);
  8. return self::processResp($response);
  9. }
  10. public static function post($client, $url, $body) {
  11. $response = self::sendRequest($client, $url, Config::HTTP_POST, $body);
  12. return self::processResp($response);
  13. }
  14. public static function put($client, $url, $body) {
  15. $response = self::sendRequest($client, $url, Config::HTTP_PUT, $body);
  16. return self::processResp($response);
  17. }
  18. public static function delete($client, $url) {
  19. $response = self::sendRequest($client, $url, Config::HTTP_DELETE, $body=null);
  20. return self::processResp($response);
  21. }
  22. private static function sendRequest($client, $url, $method, $body=null, $times=1) {
  23. self::log($client, "Send " . $method . " " . $url . ", body:" . json_encode($body) . ", times:" . $times);
  24. if (!defined('CURL_HTTP_VERSION_2_0')) {
  25. define('CURL_HTTP_VERSION_2_0', 3);
  26. }
  27. $ch = curl_init();
  28. curl_setopt($ch, CURLOPT_URL, $url);
  29. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  30. curl_setopt($ch, CURLOPT_HEADER, true);
  31. curl_setopt($ch, CURLOPT_USERAGENT, Config::USER_AGENT);
  32. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, Config::CONNECT_TIMEOUT); // 连接建立最长耗时
  33. curl_setopt($ch, CURLOPT_TIMEOUT, Config::READ_TIMEOUT); // 请求最长耗时
  34. // 设置SSL版本 1=CURL_SSLVERSION_TLSv1, 不指定使用默认值,curl会自动获取需要使用的CURL版本
  35. // curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
  36. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  37. // 如果报证书相关失败,可以考虑取消注释掉该行,强制指定证书版本
  38. //curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
  39. // 设置Basic认证
  40. curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  41. curl_setopt($ch, CURLOPT_USERPWD, $client->getAuthStr());
  42. curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
  43. // 设置Post参数
  44. if ($method === Config::HTTP_POST) {
  45. curl_setopt($ch, CURLOPT_POST, true);
  46. } else if ($method === Config::HTTP_DELETE || $method === Config::HTTP_PUT) {
  47. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  48. }
  49. if (!is_null($body)) {
  50. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
  51. }
  52. curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  53. 'Content-Type: application/json',
  54. 'Connection: Keep-Alive'
  55. ));
  56. $output = curl_exec($ch);
  57. $response = array();
  58. $errorCode = curl_errno($ch);
  59. // $msg = '';
  60. // $data = json_decode($body, true);
  61. // if (isset($data['options']['sendno'])) {
  62. // $sendno = $data['options']['sendno'];
  63. // $msg = 'sendno: ' . $sendno;
  64. // }
  65. $msg = '';
  66. if (isset($body['options']['sendno'])) {
  67. $sendno = $body['options']['sendno'];
  68. $msg = 'sendno: ' . $sendno;
  69. }
  70. if ($errorCode) {
  71. $retries = $client->getRetryTimes();
  72. if ($times < $retries) {
  73. return self::sendRequest($client, $url, $method, $body, ++$times);
  74. } else {
  75. if ($errorCode === 28) {
  76. throw new APIConnectionException($msg . "Response timeout. Your request has probably be received by JPush Server,please check that whether need to be pushed again." );
  77. } elseif ($errorCode === 56) {
  78. // resolve error[56 Problem (2) in the Chunked-Encoded data]
  79. throw new APIConnectionException($msg . "Response timeout, maybe cause by old CURL version. Your request has probably be received by JPush Server, please check that whether need to be pushed again.");
  80. } else {
  81. throw new APIConnectionException("$msg . Connect timeout. Please retry later. Error:" . $errorCode . " " . curl_error($ch));
  82. }
  83. }
  84. } else {
  85. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  86. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  87. $header_text = substr($output, 0, $header_size);
  88. $body = substr($output, $header_size);
  89. $headers = array();
  90. foreach (explode("\r\n", $header_text) as $i => $line) {
  91. if (!empty($line)) {
  92. if ($i === 0) {
  93. $headers[0] = $line;
  94. } else if (strpos($line, ": ")) {
  95. list ($key, $value) = explode(': ', $line);
  96. $headers[$key] = $value;
  97. }
  98. }
  99. }
  100. $response['headers'] = $headers;
  101. $response['body'] = $body;
  102. $response['http_code'] = $httpCode;
  103. }
  104. curl_close($ch);
  105. return $response;
  106. }
  107. public static function processResp($response) {
  108. $data = json_decode($response['body'], true);
  109. if (is_null($data)) {
  110. throw new ServiceNotAvaliable($response);
  111. } elseif ($response['http_code'] === 200) {
  112. $result = array();
  113. $result['body'] = $data;
  114. $result['http_code'] = $response['http_code'];
  115. $result['headers'] = $response['headers'];
  116. return $result;
  117. } else {
  118. throw new APIRequestException($response);
  119. }
  120. }
  121. public static function log($client, $content) {
  122. if (!is_null($client->getLogFile())) {
  123. error_log($content . "\r\n", 3, $client->getLogFile());
  124. }
  125. }
  126. }