7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
23 require_once 'Zend/Oauth.php';
25 /** Zend_Http_Client */
26 require_once 'Zend/Http/Client.php';
28 /** Zend_Oauth_Http_Utility */
29 require_once 'Zend/Oauth/Http/Utility.php';
31 /** Zend_Oauth_Config */
32 require_once 'Zend/Oauth/Config.php';
37 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
38 * @license http://framework.zend.com/license/new-bsd New BSD License
40 class Zend_Oauth_Client extends Zend_Http_Client
43 * Flag to indicate that the client has detected the server as supporting
46 public static $supportsRevisionA = false;
49 * Holds the current OAuth Configuration set encapsulated in an instance
50 * of Zend_Oauth_Config; it's not a Zend_Config instance since that level
51 * of abstraction is unnecessary and doesn't let me escape the accessors
52 * and mutators anyway!
54 * @var Zend_Oauth_Config
56 protected $_config = null;
59 * True if this request is being made with data supplied by
60 * a stream object instead of a raw encoded string.
64 protected $_streamingRequest = null;
67 * Constructor; creates a new HTTP Client instance which itself is
68 * just a typical Zend_Http_Client subclass with some OAuth icing to
69 * assist in automating OAuth parameter generation, addition and
70 * cryptographioc signing of requests.
72 * @param array $oauthOptions
74 * @param array|Zend_Config $config
77 public function __construct($oauthOptions, $uri = null, $config = null)
79 parent::__construct($uri, $config);
80 $this->_config = new Zend_Oauth_Config;
81 if ($oauthOptions !== null) {
82 if ($oauthOptions instanceof Zend_Config) {
83 $oauthOptions = $oauthOptions->toArray();
85 $this->_config->setOptions($oauthOptions);
90 * Return the current connection adapter
92 * @return Zend_Http_Client_Adapter_Interface|string $adapter
94 public function getAdapter()
96 return $this->adapter;
100 * Load the connection adapter
102 * @param Zend_Http_Client_Adapter_Interface $adapter
105 public function setAdapter($adapter)
107 if ($adapter == null) {
108 $this->adapter = $adapter;
110 parent::setAdapter($adapter);
115 * Set the streamingRequest variable which controls whether we are
116 * sending the raw (already encoded) POST data from a stream source.
118 * @param boolean $value The value to set.
121 public function setStreamingRequest($value)
123 $this->_streamingRequest = $value;
127 * Check whether the client is set to perform streaming requests.
129 * @return boolean True if yes, false otherwise.
131 public function getStreamingRequest()
133 if ($this->_streamingRequest) {
141 * Prepare the request body (for POST and PUT requests)
144 * @throws Zend_Http_Client_Exception
146 protected function _prepareBody()
148 if($this->_streamingRequest) {
149 $this->setHeaders(self::CONTENT_LENGTH,
150 $this->raw_post_data->getTotalSize());
151 return $this->raw_post_data;
154 return parent::_prepareBody();
159 * Clear all custom parameters we set.
161 * @return Zend_Http_Client
163 public function resetParameters($clearAll = false)
165 $this->_streamingRequest = false;
166 return parent::resetParameters($clearAll);
170 * Set the raw (already encoded) POST data from a stream source.
172 * This is used to support POSTing from open file handles without
173 * caching the entire body into memory. It is a wrapper around
174 * Zend_Http_Client::setRawData().
176 * @param string $data The request data
177 * @param string $enctype The encoding type
178 * @return Zend_Http_Client
180 public function setRawDataStream($data, $enctype = null)
182 $this->_streamingRequest = true;
183 return $this->setRawData($data, $enctype);
187 * Same as Zend_Http_Client::setMethod() except it also creates an
188 * Oauth specific reference to the method type.
189 * Might be defunct and removed in a later iteration.
191 * @param string $method
192 * @return Zend_Http_Client
194 public function setMethod($method = self::GET)
196 if ($method == self::GET) {
197 $this->setRequestMethod(self::GET);
198 } elseif($method == self::POST) {
199 $this->setRequestMethod(self::POST);
200 } elseif($method == self::PUT) {
201 $this->setRequestMethod(self::PUT);
202 } elseif($method == self::DELETE) {
203 $this->setRequestMethod(self::DELETE);
204 } elseif($method == self::HEAD) {
205 $this->setRequestMethod(self::HEAD);
207 return parent::setMethod($method);
211 * Same as Zend_Http_Client::request() except just before the request is
212 * executed, we automatically append any necessary OAuth parameters and
213 * sign the request using the relevant signature method.
215 * @param string $method
216 * @return Zend_Http_Response
218 public function request($method = null)
220 if ($method !== null) {
221 $this->setMethod($method);
223 $this->prepareOauth();
224 return parent::request();
228 * Performs OAuth preparation on the request before sending.
230 * This primarily means taking a request, correctly encoding and signing
231 * all parameters, and applying the correct OAuth scheme to the method
235 * @throws Zend_Oauth_Exception If POSTBODY scheme requested, but GET request method used; or if invalid request scheme provided
237 public function prepareOauth()
239 $requestScheme = $this->getRequestScheme();
240 $requestMethod = $this->getRequestMethod();
242 if ($requestScheme == Zend_Oauth::REQUEST_SCHEME_HEADER) {
243 $oauthHeaderValue = $this->getToken()->toHeader(
246 $this->_getSignableParametersAsQueryString()
248 $this->setHeaders('Authorization', $oauthHeaderValue);
249 } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_POSTBODY) {
250 if ($requestMethod == self::GET) {
251 require_once 'Zend/Oauth/Exception.php';
252 throw new Zend_Oauth_Exception(
253 'The client is configured to'
254 . ' pass OAuth parameters through a POST body but request method'
258 $raw = $this->getToken()->toQueryString(
261 $this->_getSignableParametersAsQueryString()
263 $this->setRawData($raw);
264 $this->paramsPost = array();
265 } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_QUERYSTRING) {
267 $query = $this->getUri()->getQuery();
269 $queryParts = explode('&', $this->getUri()->getQuery());
270 foreach ($queryParts as $queryPart) {
271 $kvTuple = explode('=', $queryPart);
272 $params[$kvTuple[0]] =
273 (array_key_exists(1, $kvTuple) ? $kvTuple[1] : NULL);
276 if (!empty($this->paramsPost)) {
277 $params = array_merge($params, $this->paramsPost);
278 $query = $this->getToken()->toQueryString(
279 $this->getUri(true), $this->_config, $params
282 $query = $this->getToken()->toQueryString(
283 $this->getUri(true), $this->_config, $params
285 $this->getUri()->setQuery($query);
286 $this->paramsGet = array();
288 require_once 'Zend/Oauth/Exception.php';
289 throw new Zend_Oauth_Exception('Invalid request scheme: ' . $requestScheme);
294 * Collect all signable parameters into a single array across query string
295 * and POST body. These are returned as a properly formatted single
300 protected function _getSignableParametersAsQueryString()
303 if (!empty($this->paramsGet)) {
304 $params = array_merge($params, $this->paramsGet);
305 $query = $this->getToken()->toQueryString(
306 $this->getUri(true), $this->_config, $params
309 if (!empty($this->paramsPost)) {
310 $params = array_merge($params, $this->paramsPost);
311 $query = $this->getToken()->toQueryString(
312 $this->getUri(true), $this->_config, $params
319 * Simple Proxy to the current Zend_Oauth_Config method. It's that instance
320 * which holds all configuration methods and values this object also presents
323 * @param string $method
326 * @throws Zend_Oauth_Exception if method does not exist in config object
328 public function __call($method, array $args)
330 if (!method_exists($this->_config, $method)) {
331 require_once 'Zend/Oauth/Exception.php';
332 throw new Zend_Oauth_Exception('Method does not exist: ' . $method);
334 return call_user_func_array(array($this->_config,$method), $args);