External.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php defined('SYSPATH') OR die('No direct script access.');
  2. /**
  3. * [Request_Client_External] provides a wrapper for all external request
  4. * processing. This class should be extended by all drivers handling external
  5. * requests.
  6. *
  7. * Supported out of the box:
  8. * - Curl (default)
  9. * - PECL HTTP
  10. * - Streams
  11. *
  12. * To select a specific external driver to use as the default driver, set the
  13. * following property within the Application bootstrap. Alternatively, the
  14. * client can be injected into the request object.
  15. *
  16. * @example
  17. *
  18. * // In application bootstrap
  19. * Request_Client_External::$client = 'Request_Client_Stream';
  20. *
  21. * // Add client to request
  22. * $request = Request::factory('http://some.host.tld/foo/bar')
  23. * ->client(Request_Client_External::factory('Request_Client_HTTP));
  24. *
  25. * @package Kohana
  26. * @category Base
  27. * @author Kohana Team
  28. * @copyright (c) 2008-2012 Kohana Team
  29. * @license http://kohanaframework.org/license
  30. * @uses [PECL HTTP](http://php.net/manual/en/book.http.php)
  31. */
  32. abstract class Kohana_Request_Client_External extends Request_Client {
  33. /**
  34. * Use:
  35. * - Request_Client_Curl (default)
  36. * - Request_Client_HTTP
  37. * - Request_Client_Stream
  38. *
  39. * @var string defines the external client to use by default
  40. */
  41. public static $client = 'Request_Client_Curl';
  42. /**
  43. * Factory method to create a new Request_Client_External object based on
  44. * the client name passed, or defaulting to Request_Client_External::$client
  45. * by default.
  46. *
  47. * Request_Client_External::$client can be set in the application bootstrap.
  48. *
  49. * @param array $params parameters to pass to the client
  50. * @param string $client external client to use
  51. * @return Request_Client_External
  52. * @throws Request_Exception
  53. */
  54. public static function factory(array $params = array(), $client = NULL)
  55. {
  56. if ($client === NULL)
  57. {
  58. $client = Request_Client_External::$client;
  59. }
  60. $client = new $client($params);
  61. if ( ! $client instanceof Request_Client_External)
  62. {
  63. throw new Request_Exception('Selected client is not a Request_Client_External object.');
  64. }
  65. return $client;
  66. }
  67. /**
  68. * @var array curl options
  69. * @link http://www.php.net/manual/function.curl-setopt
  70. * @link http://www.php.net/manual/http.request.options
  71. */
  72. protected $_options = array();
  73. /**
  74. * Processes the request, executing the controller action that handles this
  75. * request, determined by the [Route].
  76. *
  77. * 1. Before the controller action is called, the [Controller::before] method
  78. * will be called.
  79. * 2. Next the controller action will be called.
  80. * 3. After the controller action is called, the [Controller::after] method
  81. * will be called.
  82. *
  83. * By default, the output from the controller is captured and returned, and
  84. * no headers are sent.
  85. *
  86. * $request->execute();
  87. *
  88. * @param Request $request A request object
  89. * @param Response $response A response object
  90. * @return Response
  91. * @throws Kohana_Exception
  92. * @uses [Kohana::$profiling]
  93. * @uses [Profiler]
  94. */
  95. public function execute_request(Request $request, Response $response)
  96. {
  97. if (Kohana::$profiling)
  98. {
  99. // Set the benchmark name
  100. $benchmark = '"'.$request->uri().'"';
  101. if ($request !== Request::$initial AND Request::$current)
  102. {
  103. // Add the parent request uri
  104. $benchmark .= ' « "'.Request::$current->uri().'"';
  105. }
  106. // Start benchmarking
  107. $benchmark = Profiler::start('Requests', $benchmark);
  108. }
  109. // Store the current active request and replace current with new request
  110. $previous = Request::$current;
  111. Request::$current = $request;
  112. // Resolve the POST fields
  113. if ($post = $request->post())
  114. {
  115. $request->body(http_build_query($post, NULL, '&'))
  116. ->headers('content-type', 'application/x-www-form-urlencoded');
  117. }
  118. // If Kohana expose, set the user-agent
  119. if (Kohana::$expose)
  120. {
  121. $request->headers('user-agent', Kohana::version());
  122. }
  123. try
  124. {
  125. $response = $this->_send_message($request, $response);
  126. }
  127. catch (Exception $e)
  128. {
  129. // Restore the previous request
  130. Request::$current = $previous;
  131. if (isset($benchmark))
  132. {
  133. // Delete the benchmark, it is invalid
  134. Profiler::delete($benchmark);
  135. }
  136. // Re-throw the exception
  137. throw $e;
  138. }
  139. // Restore the previous request
  140. Request::$current = $previous;
  141. if (isset($benchmark))
  142. {
  143. // Stop the benchmark
  144. Profiler::stop($benchmark);
  145. }
  146. // Return the response
  147. return $response;
  148. }
  149. /**
  150. * Set and get options for this request.
  151. *
  152. * @param mixed $key Option name, or array of options
  153. * @param mixed $value Option value
  154. * @return mixed
  155. * @return Request_Client_External
  156. */
  157. public function options($key = NULL, $value = NULL)
  158. {
  159. if ($key === NULL)
  160. return $this->_options;
  161. if (is_array($key))
  162. {
  163. $this->_options = $key;
  164. }
  165. elseif ($value === NULL)
  166. {
  167. return Arr::get($this->_options, $key);
  168. }
  169. else
  170. {
  171. $this->_options[$key] = $value;
  172. }
  173. return $this;
  174. }
  175. /**
  176. * Sends the HTTP message [Request] to a remote server and processes
  177. * the response.
  178. *
  179. * @param Request $request Request to send
  180. * @param Response $response Response to send
  181. * @return Response
  182. */
  183. abstract protected function _send_message(Request $request, Response $response);
  184. } // End Kohana_Request_Client_External