You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.3 KiB

  1. <?php
  2. namespace p3k\HTTP;
  3. class Curl implements Transport {
  4. protected $_timeout = 4;
  5. protected $_max_redirects = 8;
  6. public function set_max_redirects($max) {
  7. $this->_max_redirects = $max;
  8. }
  9. public function set_timeout($timeout) {
  10. $this->_timeout = $timeout;
  11. }
  12. public function get($url, $headers=[]) {
  13. $ch = curl_init($url);
  14. $this->_set_curlopts($ch, $url);
  15. if($headers)
  16. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  17. $response = curl_exec($ch);
  18. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  19. $header_str = trim(substr($response, 0, $header_size));
  20. return array(
  21. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  22. 'header' => $header_str,
  23. 'body' => substr($response, $header_size),
  24. 'error' => self::error_string_from_code(curl_errno($ch)),
  25. 'error_description' => curl_error($ch),
  26. 'url' => curl_getinfo($ch, CURLINFO_EFFECTIVE_URL),
  27. 'debug' => $response
  28. );
  29. }
  30. public function post($url, $body, $headers=[]) {
  31. $ch = curl_init($url);
  32. $this->_set_curlopts($ch, $url);
  33. curl_setopt($ch, CURLOPT_POST, true);
  34. curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
  35. if($headers)
  36. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  37. $response = curl_exec($ch);
  38. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  39. $header_str = trim(substr($response, 0, $header_size));
  40. return array(
  41. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  42. 'header' => $header_str,
  43. 'body' => substr($response, $header_size),
  44. 'error' => self::error_string_from_code(curl_errno($ch)),
  45. 'error_description' => curl_error($ch),
  46. 'url' => curl_getinfo($ch, CURLINFO_EFFECTIVE_URL),
  47. 'debug' => $response
  48. );
  49. }
  50. public function head($url) {
  51. $ch = curl_init($url);
  52. $this->_set_curlopts($ch, $url);
  53. curl_setopt($ch, CURLOPT_NOBODY, true);
  54. $response = curl_exec($ch);
  55. return array(
  56. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  57. 'header' => trim($response),
  58. 'error' => self::error_string_from_code(curl_errno($ch)),
  59. 'error_description' => curl_error($ch),
  60. 'url' => curl_getinfo($ch, CURLINFO_EFFECTIVE_URL),
  61. 'debug' => $response
  62. );
  63. }
  64. private function _set_curlopts($ch, $url) {
  65. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  66. curl_setopt($ch, CURLOPT_HEADER, true);
  67. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  68. curl_setopt($ch, CURLOPT_MAXREDIRS, $this->_max_redirects);
  69. curl_setopt($ch, CURLOPT_TIMEOUT_MS, round($this->_timeout * 1000));
  70. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 2000);
  71. }
  72. public static function error_string_from_code($code) {
  73. switch($code) {
  74. case 0:
  75. return '';
  76. case CURLE_COULDNT_RESOLVE_HOST:
  77. return 'dns_error';
  78. case CURLE_COULDNT_CONNECT:
  79. return 'connect_error';
  80. case CURLE_OPERATION_TIMEDOUT:
  81. return 'timeout';
  82. case CURLE_SSL_CONNECT_ERROR:
  83. return 'ssl_error';
  84. case CURLE_SSL_CERTPROBLEM:
  85. return 'ssl_cert_error';
  86. case CURLE_SSL_CIPHER:
  87. return 'ssl_unsupported_cipher';
  88. case CURLE_SSL_CACERT:
  89. return 'ssl_cert_error';
  90. case CURLE_TOO_MANY_REDIRECTS:
  91. return 'too_many_redirects';
  92. default:
  93. return 'unknown';
  94. }
  95. }
  96. }