1<?php defined('SYSPATH') OR die('No direct script access.');
2/**
3 * [Request_Client_External] HTTP driver performs external requests using the
4 * php-http extension. To use this driver, ensure the following is completed
5 * before executing an external request- ideally in the application bootstrap.
6 *
7 * @example
8 *
9 *       // In application bootstrap
10 *       Request_Client_External::$client = 'Request_Client_HTTP';
11 *
12 * @package    Kohana
13 * @category   Base
14 * @author     Kohana Team
15 * @copyright  (c) 2008-2012 Kohana Team
16 * @license    http://kohanaframework.org/license
17 * @uses       [PECL HTTP](http://php.net/manual/en/book.http.php)
18 */
19class Kohana_Request_Client_HTTP extends Request_Client_External {
20
21	/**
22	 * Creates a new `Request_Client` object,
23	 * allows for dependency injection.
24	 *
25	 * @param   array    $params Params
26	 * @throws  Request_Exception
27	 */
28	public function __construct(array $params = array())
29	{
30		// Check that PECL HTTP supports requests
31		if ( ! http_support(HTTP_SUPPORT_REQUESTS))
32		{
33			throw new Request_Exception('Need HTTP request support!');
34		}
35
36		// Carry on
37		parent::__construct($params);
38	}
39
40	/**
41	 * @var     array     curl options
42	 * @link    http://www.php.net/manual/function.curl-setopt
43	 */
44	protected $_options = array();
45
46	/**
47	 * Sends the HTTP message [Request] to a remote server and processes
48	 * the response.
49	 *
50	 * @param   Request   $request  request to send
51	 * @param   Response  $request  response to send
52	 * @return  Response
53	 */
54	public function _send_message(Request $request, Response $response)
55	{
56		$http_method_mapping = array(
57			HTTP_Request::GET     => HTTPRequest::METH_GET,
58			HTTP_Request::HEAD    => HTTPRequest::METH_HEAD,
59			HTTP_Request::POST    => HTTPRequest::METH_POST,
60			HTTP_Request::PUT     => HTTPRequest::METH_PUT,
61			HTTP_Request::DELETE  => HTTPRequest::METH_DELETE,
62			HTTP_Request::OPTIONS => HTTPRequest::METH_OPTIONS,
63			HTTP_Request::TRACE   => HTTPRequest::METH_TRACE,
64			HTTP_Request::CONNECT => HTTPRequest::METH_CONNECT,
65		);
66
67		// Create an http request object
68		$http_request = new HTTPRequest($request->uri(), $http_method_mapping[$request->method()]);
69
70		if ($this->_options)
71		{
72			// Set custom options
73			$http_request->setOptions($this->_options);
74		}
75
76		// Set headers
77		$http_request->setHeaders($request->headers()->getArrayCopy());
78
79		// Set cookies
80		$http_request->setCookies($request->cookie());
81
82		// Set query data (?foo=bar&bar=foo)
83		$http_request->setQueryData($request->query());
84
85		// Set the body
86		if ($request->method() == HTTP_Request::PUT)
87		{
88			$http_request->addPutData($request->body());
89		}
90		else
91		{
92			$http_request->setBody($request->body());
93		}
94
95		try
96		{
97			$http_request->send();
98		}
99		catch (HTTPRequestException $e)
100		{
101			throw new Request_Exception($e->getMessage());
102		}
103		catch (HTTPMalformedHeaderException $e)
104		{
105			throw new Request_Exception($e->getMessage());
106		}
107		catch (HTTPEncodingException $e)
108		{
109			throw new Request_Exception($e->getMessage());
110		}
111
112		// Build the response
113		$response->status($http_request->getResponseCode())
114			->headers($http_request->getResponseHeader())
115			->cookie($http_request->getResponseCookies())
116			->body($http_request->getResponseBody());
117
118		return $response;
119	}
120
121}
122