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.

115 lines
4.0 KiB

  1. <?php
  2. namespace p3k;
  3. class HTTP {
  4. public $timeout = 3;
  5. public $max_redirects = 8;
  6. public function get($url) {
  7. $ch = curl_init($url);
  8. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  9. curl_setopt($ch, CURLOPT_HEADER, true);
  10. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  11. curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirects);
  12. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  13. $response = curl_exec($ch);
  14. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  15. return array(
  16. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  17. 'headers' => self::parse_headers(trim(substr($response, 0, $header_size))),
  18. 'body' => substr($response, $header_size),
  19. 'error' => self::error_string_from_code(curl_errno($ch)),
  20. 'error_description' => curl_error($ch),
  21. 'error_code' => curl_errno($ch),
  22. );
  23. }
  24. public function post($url, $body, $headers=array()) {
  25. $ch = curl_init($url);
  26. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  27. curl_setopt($ch, CURLOPT_POST, true);
  28. curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
  29. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  30. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  31. curl_setopt($ch, CURLOPT_HEADER, true);
  32. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  33. $response = curl_exec($ch);
  34. $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  35. return array(
  36. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  37. 'headers' => self::parse_headers(trim(substr($response, 0, $header_size))),
  38. 'body' => substr($response, $header_size),
  39. 'error' => self::error_string_from_code(curl_errno($ch)),
  40. 'error_description' => curl_error($ch),
  41. 'error_code' => curl_errno($ch),
  42. );
  43. }
  44. public function head($url) {
  45. $ch = curl_init($url);
  46. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  47. curl_setopt($ch, CURLOPT_HEADER, true);
  48. curl_setopt($ch, CURLOPT_NOBODY, true);
  49. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  50. curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirects);
  51. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  52. $response = curl_exec($ch);
  53. return array(
  54. 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  55. 'headers' => self::parse_headers(trim($response)),
  56. 'error' => self::error_string_from_code(curl_errno($ch)),
  57. 'error_description' => curl_error($ch),
  58. 'error_code' => curl_errno($ch),
  59. );
  60. }
  61. public static function error_string_from_code($code) {
  62. switch($code) {
  63. case 0:
  64. return '';
  65. case CURLE_COULDNT_RESOLVE_HOST:
  66. return 'dns_error';
  67. case CURLE_COULDNT_CONNECT:
  68. return 'connect_error';
  69. case CURLE_OPERATION_TIMEDOUT:
  70. return 'timeout';
  71. case CURLE_SSL_CONNECT_ERROR:
  72. return 'ssl_error';
  73. case CURLE_SSL_CERTPROBLEM:
  74. return 'ssl_cert_error';
  75. case CURLE_SSL_CIPHER:
  76. return 'ssl_unsupported_cipher';
  77. case CURLE_SSL_CACERT:
  78. return 'ssl_cert_error';
  79. case CURLE_TOO_MANY_REDIRECTS:
  80. return 'too_many_redirects';
  81. default:
  82. return 'unknown';
  83. }
  84. }
  85. public static function parse_headers($headers) {
  86. $retVal = array();
  87. $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $headers));
  88. foreach($fields as $field) {
  89. if(preg_match('/([^:]+): (.+)/m', $field, $match)) {
  90. $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', function($m) {
  91. return strtoupper($m[0]);
  92. }, strtolower(trim($match[1])));
  93. // If there's already a value set for the header name being returned, turn it into an array and add the new value
  94. $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', function($m) {
  95. return strtoupper($m[0]);
  96. }, strtolower(trim($match[1])));
  97. if(isset($retVal[$match[1]])) {
  98. if(!is_array($retVal[$match[1]]))
  99. $retVal[$match[1]] = array($retVal[$match[1]]);
  100. $retVal[$match[1]][] = $match[2];
  101. } else {
  102. $retVal[$match[1]] = trim($match[2]);
  103. }
  104. }
  105. }
  106. return $retVal;
  107. }
  108. }