/classes/httprequest/XEHttpRequest.class.php

http://xe-core.googlecode.com/ · PHP · 244 lines · 147 code · 35 blank · 62 comment · 16 complexity · babfd6eb034ac27d2be3c6c8a6d30e57 MD5 · raw file

  1. <?php
  2. /**
  3. * - HttpRequest class
  4. * - a class that is designed to be used for sending out HTTP request to an external server and retrieving response
  5. * - Connection: keep-alive is not supported
  6. * @author NHN (developers@xpressengine.com)
  7. * @package /classes/httprequest
  8. * @version 0.1
  9. */
  10. class XEHttpRequest
  11. {
  12. /**
  13. * target host
  14. * @var string
  15. */
  16. var $m_host;
  17. /**
  18. * target Port
  19. * @var int
  20. */
  21. var $m_port;
  22. /**
  23. * target header
  24. * @var array
  25. */
  26. var $m_headers;
  27. /**
  28. * constructor
  29. * @return void
  30. */
  31. function XEHttpRequest($host, $port)
  32. {
  33. $this->m_host = $host;
  34. $this->m_port = $port;
  35. $this->m_headers = array();
  36. }
  37. /**
  38. * Mether to add key/value pair to the HTTP request header
  39. * @param int|string $key HTTP header element
  40. * @param string $value value string for HTTP header element
  41. * @return void
  42. */
  43. function addToHeader($key, $value)
  44. {
  45. $this->m_headers[$key] = $value;
  46. }
  47. /**
  48. * Send HTTP message to the host
  49. * @param string $target ip or url of the external server
  50. * @param string $method HTTP method such as GET and POST
  51. * @param int $timeout time out value for HTTP request expiration
  52. * @param array $post_vars variables to send
  53. * @return object Returns an object containing HTTP Response body and HTTP response code
  54. */
  55. function send($target = '/', $method = 'GET', $timeout = 3, $post_vars = NULL)
  56. {
  57. static $allow_methods = NULL;
  58. $this->addToHeader('Host', $this->m_host);
  59. $this->addToHeader('Connection', 'close');
  60. $method = strtoupper($method);
  61. if(!$allow_methods)
  62. {
  63. $allow_methods = explode(' ', 'GET POST PUT');
  64. }
  65. if(!in_array($method, $allow_methods))
  66. {
  67. $method = $allow_methods[0];
  68. }
  69. // $timeout should be an integer that is bigger than zero
  70. $timout = max((int) $timeout, 0);
  71. // list of post variables
  72. if(!is_array($post_vars))
  73. {
  74. $post_vars = array();
  75. }
  76. if(FALSE && is_callable('curl_init'))
  77. {
  78. return $this->sendWithCurl($target, $method, $timeout, $post_vars);
  79. }
  80. else
  81. {
  82. return $this->sendWithSock($target, $method, $timeout, $post_vars);
  83. }
  84. }
  85. /**
  86. * Send a request with the file socket
  87. * @param string $target ip or url of the external server
  88. * @param string $method HTTP method such as GET and POST
  89. * @param int $timeout time out value for HTTP request expiration
  90. * @param array $post_vars variables to send
  91. * @return object Returns an object containing HTTP Response body and HTTP response code
  92. */
  93. function sendWithSock($target, $method, $timeout, $post_vars)
  94. {
  95. static $crlf = "\r\n";
  96. $sock = @fsockopen($this->m_host, $this->m_port, $errno, $errstr, $timeout);
  97. if(!$sock)
  98. {
  99. return new Object(-1, 'socket_connect_failed');
  100. }
  101. $headers = $this->m_headers + array();
  102. if(!isset($headers['Accept-Encoding']))
  103. {
  104. $headers['Accept-Encoding'] = 'identity';
  105. }
  106. // post body
  107. $post_body = '';
  108. if($method == 'POST' && count($post_vars))
  109. {
  110. foreach($post_vars as $key => $value)
  111. {
  112. $post_body .= urlencode($key) . '=' . urlencode($value) . '&';
  113. }
  114. $post_body = substr($post_body, 0, -1);
  115. $headers['Content-Length'] = strlen($post_body);
  116. $headers['Content-Type'] = 'application/x-www-form-urlencoded';
  117. }
  118. $request = "$method $target HTTP/1.1$crlf";
  119. foreach($headers as $equiv => $content)
  120. {
  121. $request .= "$equiv: $content$crlf";
  122. }
  123. $request .= $crlf . $post_body;
  124. fwrite($sock, $request);
  125. list($httpver, $code, $status) = preg_split('/ +/', rtrim(fgets($sock)), 3);
  126. // read response headers
  127. $is_chunked = FALSE;
  128. while(strlen(trim($line = fgets($sock))))
  129. {
  130. list($equiv, $content) = preg_split('/ *: */', rtrim($line), 1);
  131. if(!strcasecmp($equiv, 'Transfer-Encoding') && $content == 'chunked')
  132. {
  133. $is_chunked = TRUE;
  134. }
  135. }
  136. $body = '';
  137. while(!feof($sock))
  138. {
  139. if($is_chunked)
  140. {
  141. $chunk_size = hexdec(fgets($sock));
  142. if($chunk_size)
  143. {
  144. $body .= fread($sock, $chunk_size);
  145. }
  146. }
  147. else
  148. {
  149. $body .= fgets($sock, 512);
  150. }
  151. }
  152. fclose($sock);
  153. $ret = new stdClass;
  154. $ret->result_code = $code;
  155. $ret->body = $body;
  156. return $ret;
  157. }
  158. /**
  159. * Send a request with the curl library
  160. * @param string $target ip or url of the external server
  161. * @param string $method HTTP method such as GET and POST
  162. * @param int $timeout time out value for HTTP request expiration
  163. * @param array $post_vars variables to send
  164. * @return object Returns an object containing HTTP Response body and HTTP response code
  165. */
  166. function sendWithCurl($target, $method, $timeout, $post_vars)
  167. {
  168. $headers = $this->m_headers + array();
  169. // creat a new cURL resource
  170. $ch = curl_init();
  171. $headers['Expect'] = '';
  172. // set URL and other appropriate options
  173. curl_setopt($ch, CURLOPT_URL, "http://{$this->m_host}{$target}");
  174. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  175. curl_setopt($ch, CURLOPT_PORT, $this->m_port);
  176. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  177. curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  178. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  179. switch($method)
  180. {
  181. case 'GET': curl_setopt($ch, CURLOPT_HTTPGET, true);
  182. break;
  183. case 'PUT': curl_setopt($ch, CURLOPT_PUT, true);
  184. break;
  185. case 'POST':
  186. curl_setopt($ch, CURLOPT_POST, true);
  187. curl_setopt($ch, CURLOPT_POSTFIELDS, $post_vars);
  188. break;
  189. }
  190. $arr_headers = array();
  191. foreach($headers as $key => $value)
  192. {
  193. $arr_headers[] = "$key: $value";
  194. }
  195. curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_headers);
  196. $body = curl_exec($ch);
  197. if(curl_errno($ch))
  198. {
  199. return new Object(-1, 'socket_connect_failed');
  200. }
  201. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  202. $ret = new stdClass;
  203. $ret->result_code = $code;
  204. $ret->body = $body;
  205. return $ret;
  206. }
  207. }
  208. /* End of file XEHttpRequest.class.php */
  209. /* Location: ./classes/httprequest/XEHttpRequest.class.php */