TinyHttp.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. /**
  3. * Based on TinyHttp from https://gist.github.com/618157.
  4. * Copyright 2011, Neuman Vong. BSD License.
  5. */
  6. class Services_Twilio_TinyHttpException extends ErrorException {}
  7. /**
  8. * An HTTP client that makes requests
  9. *
  10. * :param string $uri: The base uri to use for requests
  11. * :param array $kwargs: An array of additional arguments to pass to the
  12. * library. Accepted arguments are:
  13. *
  14. * - **debug** - Print the HTTP request before making it to Twilio
  15. * - **curlopts** - An array of keys and values that are passed to
  16. * ``curl_setopt_array``.
  17. *
  18. * Here's an example. This is the default HTTP client used by the library.
  19. *
  20. * .. code-block:: php
  21. *
  22. * $_http = new Services_Twilio_TinyHttp(
  23. * "https://api.twilio.com",
  24. * array("curlopts" => array(
  25. * CURLOPT_USERAGENT => self::USER_AGENT,
  26. * CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'),
  27. * CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem',
  28. * ))
  29. * );
  30. */
  31. class Services_Twilio_TinyHttp {
  32. var $user, $pass, $scheme, $host, $port, $debug, $curlopts;
  33. public function __construct($uri = '', $kwargs = array()) {
  34. foreach (parse_url($uri) as $name => $value) $this->$name = $value;
  35. $this->debug = isset($kwargs['debug']) ? !!$kwargs['debug'] : NULL;
  36. $this->curlopts = isset($kwargs['curlopts']) ? $kwargs['curlopts'] : array();
  37. }
  38. public function __call($name, $args) {
  39. list($res, $req_headers, $req_body) = $args + array(0, array(), '');
  40. $opts = $this->curlopts + array(
  41. CURLOPT_URL => "$this->scheme://$this->host$res",
  42. CURLOPT_HEADER => TRUE,
  43. CURLOPT_RETURNTRANSFER => TRUE,
  44. CURLOPT_INFILESIZE => -1,
  45. CURLOPT_POSTFIELDS => NULL,
  46. CURLOPT_TIMEOUT => 60,
  47. );
  48. foreach ($req_headers as $k => $v) $opts[CURLOPT_HTTPHEADER][] = "$k: $v";
  49. if ($this->port) $opts[CURLOPT_PORT] = $this->port;
  50. if ($this->debug) $opts[CURLINFO_HEADER_OUT] = TRUE;
  51. if ($this->user && $this->pass) $opts[CURLOPT_USERPWD] = "$this->user:$this->pass";
  52. switch ($name) {
  53. case 'get':
  54. $opts[CURLOPT_HTTPGET] = TRUE;
  55. break;
  56. case 'post':
  57. $opts[CURLOPT_POST] = TRUE;
  58. $opts[CURLOPT_POSTFIELDS] = $req_body;
  59. break;
  60. case 'put':
  61. $opts[CURLOPT_PUT] = TRUE;
  62. if (strlen($req_body)) {
  63. if ($buf = fopen('php://memory', 'w+')) {
  64. fwrite($buf, $req_body);
  65. fseek($buf, 0);
  66. $opts[CURLOPT_INFILE] = $buf;
  67. $opts[CURLOPT_INFILESIZE] = strlen($req_body);
  68. } else throw new Services_Twilio_TinyHttpException('unable to open temporary file');
  69. }
  70. break;
  71. case 'head':
  72. $opts[CURLOPT_NOBODY] = TRUE;
  73. break;
  74. default:
  75. $opts[CURLOPT_CUSTOMREQUEST] = strtoupper($name);
  76. break;
  77. }
  78. try {
  79. if ($curl = curl_init()) {
  80. if (curl_setopt_array($curl, $opts)) {
  81. if ($response = curl_exec($curl)) {
  82. $parts = explode("\r\n\r\n", $response, 3);
  83. list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')
  84. ? array($parts[1], $parts[2])
  85. : array($parts[0], $parts[1]);
  86. $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  87. if ($this->debug) {
  88. error_log(
  89. curl_getinfo($curl, CURLINFO_HEADER_OUT) .
  90. $req_body
  91. );
  92. }
  93. $header_lines = explode("\r\n", $head);
  94. array_shift($header_lines);
  95. foreach ($header_lines as $line) {
  96. list($key, $value) = explode(":", $line, 2);
  97. $headers[$key] = trim($value);
  98. }
  99. curl_close($curl);
  100. if (isset($buf) && is_resource($buf)) {
  101. fclose($buf);
  102. }
  103. return array($status, $headers, $body);
  104. } else {
  105. throw new Services_Twilio_TinyHttpException(curl_error($curl));
  106. }
  107. } else throw new Services_Twilio_TinyHttpException(curl_error($curl));
  108. } else throw new Services_Twilio_TinyHttpException('unable to initialize cURL');
  109. } catch (ErrorException $e) {
  110. if (is_resource($curl)) curl_close($curl);
  111. if (isset($buf) && is_resource($buf)) fclose($buf);
  112. throw $e;
  113. }
  114. }
  115. public function authenticate($user, $pass) {
  116. $this->user = $user;
  117. $this->pass = $pass;
  118. }
  119. }