/application/helpers/MY_remote.php

https://github.com/yamamoto123/Ushahidi_Web · PHP · 240 lines · 109 code · 42 blank · 89 comment · 15 complexity · b4a57b2c467a97668e97b0f812048f2c MD5 · raw file

  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Remote url helper, extends generic remote_Core
  4. *
  5. * @package Core
  6. * @author zextra <zextra@gmail.com>
  7. * @license http://kohanaphp.com/license.html
  8. */
  9. class remote extends remote_Core {
  10. /**
  11. * Shorthand method to GET data from remote url
  12. *
  13. * @param string $url
  14. * @param array $headers
  15. * @return HTTP_Response
  16. */
  17. public static function get($url, $headers = array())
  18. {
  19. return self::request('GET', $url, $headers);
  20. }
  21. /**
  22. * Shorthand method to POST data to remote url
  23. *
  24. * @param string $url
  25. * @param array $data
  26. * @param array $headers
  27. * @return HTTP_Response
  28. */
  29. public static function post($url, $data = array(), $headers = array())
  30. {
  31. return self::request('POST', $url, $headers, $data);
  32. }
  33. /**
  34. * Method that allows sending any kind of HTTP request to remote url
  35. *
  36. * @param string $method
  37. * @param string $url
  38. * @param array $headers
  39. * @param array $data
  40. * @return HTTP_Response
  41. */
  42. public static function request($method, $url, $headers = array(), $data = array())
  43. {
  44. $valid_methods = array('POST', 'GET', 'PUT', 'DELETE');
  45. $method = utf8::strtoupper($method);
  46. if ( ! valid::url($url, 'http'))
  47. return FALSE;
  48. if ( ! in_array($method, $valid_methods))
  49. return FALSE;
  50. // Get the hostname and path
  51. $url = parse_url($url);
  52. if (empty($url['path']))
  53. {
  54. // Request the root document
  55. $url['path'] = '/';
  56. }
  57. // Open a remote connection
  58. $remote = fsockopen($url['host'], 80, $errno, $errstr, 5);
  59. if ( ! is_resource($remote))
  60. return FALSE;
  61. // Set CRLF
  62. $CRLF = "\r\n";
  63. $path = $url['path'];
  64. if ($method == 'GET' AND ! empty($url['query']))
  65. $path .= '?'.$url['query'];
  66. $headers_default = array(
  67. 'Host' => $url['host'],
  68. 'Connection' => 'close',
  69. 'User-Agent' => 'Ushahidi Scheduler (+http://ushahidi.com/)',
  70. );
  71. $body_content = '';
  72. if ($method != 'GET')
  73. {
  74. $headers_default['Content-Type'] = 'application/x-www-form-urlencoded';
  75. if (count($data) > 0)
  76. {
  77. $body_content = http_build_query($data);
  78. }
  79. $headers_default['Content-Length'] = strlen($body_content);
  80. }
  81. $headers = array_merge($headers_default, $headers);
  82. // Send request
  83. $request = $method.' '.$path.' HTTP/1.0'.$CRLF;
  84. foreach ($headers as $key => $value)
  85. {
  86. $request .= $key.': '.$value.$CRLF;
  87. }
  88. // Send one more CRLF to terminate the headers
  89. $request .= $CRLF;
  90. if ($body_content)
  91. {
  92. $request .= $body_content.$CRLF;
  93. }
  94. fwrite($remote, $request);
  95. $response = '';
  96. while ( ! feof($remote))
  97. {
  98. // Get 1K from buffer
  99. $response .= fread($remote, 1024);
  100. }
  101. // Close the connection
  102. fclose($remote);
  103. return new HTTP_Response($response, $method);
  104. }
  105. }
  106. /**
  107. * Very simple class that handles raw response received from remote host
  108. *
  109. * @package Core
  110. */
  111. class HTTP_Response {
  112. /**
  113. * HTTP method
  114. *
  115. * @var string
  116. */
  117. protected $method;
  118. /**
  119. * HTTP status code
  120. *
  121. * @var integer
  122. */
  123. protected $status;
  124. /**
  125. * Complete request, as received from remote host
  126. *
  127. * @var string
  128. */
  129. protected $response;
  130. /**
  131. * Headers received from remote host
  132. *
  133. * @var string
  134. */
  135. protected $headers;
  136. /**
  137. * Body received from remote host
  138. *
  139. * @var string
  140. */
  141. protected $body;
  142. public function __construct($full_response, $method)
  143. {
  144. $this->method = $method;
  145. $this->response = $full_response;
  146. $this->parse();
  147. }
  148. /**
  149. * Splits $this->response into header and body, also extract status code
  150. *
  151. * @return void
  152. */
  153. protected function parse()
  154. {
  155. // split response by newlines and detect first empty line (between header and body)
  156. $lines = explode("\n", $this->response);
  157. $headers = array();
  158. foreach ($lines as $line)
  159. {
  160. // each time we take one line, we will remove that line, until we find empty one
  161. $headers[] = array_shift($lines);
  162. if ($line !== '' AND preg_match('#^HTTP/1\.[01] (\d{3})#', $line, $matches))
  163. {
  164. // Response code found
  165. $this->status = (int) $matches[1];
  166. }
  167. if ($line === "\r" or $line === "")
  168. {
  169. break;
  170. }
  171. }
  172. $this->headers = trim(implode("\n", $headers));
  173. $this->body = implode("\n", $lines);
  174. }
  175. /**
  176. * Returns only body() if object is stringified
  177. *
  178. * @return unknown
  179. */
  180. public function __toString()
  181. {
  182. return (string) $this->body();
  183. }
  184. /**
  185. * Basic getter for class members
  186. *
  187. * @param string $method
  188. * @param array $args
  189. * @return mixed
  190. */
  191. public function __call($method, array $args)
  192. {
  193. if (isset($this->$method) AND count($args) == 0)
  194. {
  195. return $this->$method;
  196. }
  197. }
  198. }