File indexing completed on 2024-12-22 05:36:53

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Oauth
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /** Zend_Oauth */
0023 // require_once 'Zend/Oauth.php';
0024 
0025 /** Zend_Http_Client */
0026 // require_once 'Zend/Http/Client.php';
0027 
0028 /** Zend_Oauth_Http_Utility */
0029 // require_once 'Zend/Oauth/Http/Utility.php';
0030 
0031 /** Zend_Oauth_Config */
0032 // require_once 'Zend/Oauth/Config.php';
0033 
0034 /**
0035  * @category   Zend
0036  * @package    Zend_Oauth
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 class Zend_Oauth_Client extends Zend_Http_Client
0041 {
0042     /**
0043      * Flag to indicate that the client has detected the server as supporting
0044      * OAuth 1.0a
0045      */
0046     public static $supportsRevisionA = false;
0047 
0048     /**
0049      * Holds the current OAuth Configuration set encapsulated in an instance
0050      * of Zend_Oauth_Config; it's not a Zend_Config instance since that level
0051      * of abstraction is unnecessary and doesn't let me escape the accessors
0052      * and mutators anyway!
0053      *
0054      * @var Zend_Oauth_Config
0055      */
0056     protected $_config = null;
0057 
0058     /**
0059      * True if this request is being made with data supplied by
0060      * a stream object instead of a raw encoded string.
0061      *
0062      * @var bool
0063      */
0064     protected $_streamingRequest = null;
0065 
0066     /**
0067      * Constructor; creates a new HTTP Client instance which itself is
0068      * just a typical Zend_Http_Client subclass with some OAuth icing to
0069      * assist in automating OAuth parameter generation, addition and
0070      * cryptographioc signing of requests.
0071      *
0072      * @param  array|Zend_Config $oauthOptions
0073      * @param  string            $uri
0074      * @param  array|Zend_Config $config
0075      * @return void
0076      */
0077     public function __construct($oauthOptions, $uri = null, $config = null)
0078     {
0079         if ($config instanceof Zend_Config && !isset($config->rfc3986_strict)) {
0080             $config                   = $config->toArray();
0081             $config['rfc3986_strict'] = true;
0082         } else if (null === $config ||
0083                    (is_array($config) && !isset($config['rfc3986_strict']))) {
0084             $config['rfc3986_strict'] = true;
0085         }
0086         parent::__construct($uri, $config);
0087         $this->_config = new Zend_Oauth_Config;
0088         if ($oauthOptions !== null) {
0089             if ($oauthOptions instanceof Zend_Config) {
0090                 $oauthOptions = $oauthOptions->toArray();
0091             }
0092             $this->_config->setOptions($oauthOptions);
0093         }
0094     }
0095 
0096    /**
0097      * Load the connection adapter
0098      *
0099      * @param Zend_Http_Client_Adapter_Interface $adapter
0100      * @return void
0101      */
0102     public function setAdapter($adapter)
0103     {
0104         if ($adapter == null) {
0105             $this->adapter = $adapter;
0106         } else {
0107               parent::setAdapter($adapter);
0108         }
0109     }
0110 
0111     /**
0112      * Set the streamingRequest variable which controls whether we are
0113      * sending the raw (already encoded) POST data from a stream source.
0114      *
0115      * @param boolean $value The value to set.
0116      * @return void
0117      */
0118     public function setStreamingRequest($value)
0119     {
0120         $this->_streamingRequest = $value;
0121     }
0122 
0123     /**
0124      * Check whether the client is set to perform streaming requests.
0125      *
0126      * @return boolean True if yes, false otherwise.
0127      */
0128     public function getStreamingRequest()
0129     {
0130         if ($this->_streamingRequest) {
0131             return true;
0132         } else {
0133             return false;
0134         }
0135     }
0136 
0137     /**
0138      * Prepare the request body (for POST and PUT requests)
0139      *
0140      * @return string
0141      * @throws Zend_Http_Client_Exception
0142      */
0143     protected function _prepareBody()
0144     {
0145         if($this->_streamingRequest) {
0146             $this->setHeaders(self::CONTENT_LENGTH,
0147                 $this->raw_post_data->getTotalSize());
0148             return $this->raw_post_data;
0149         }
0150         else {
0151             return parent::_prepareBody();
0152         }
0153     }
0154 
0155     /**
0156      * Clear all custom parameters we set.
0157      *
0158      * @return Zend_Http_Client
0159      */
0160     public function resetParameters($clearAll = false)
0161     {
0162         $this->_streamingRequest = false;
0163         return parent::resetParameters($clearAll);
0164     }
0165 
0166     /**
0167      * Set the raw (already encoded) POST data from a stream source.
0168      *
0169      * This is used to support POSTing from open file handles without
0170      * caching the entire body into memory. It is a wrapper around
0171      * Zend_Http_Client::setRawData().
0172      *
0173      * @param string $data The request data
0174      * @param string $enctype The encoding type
0175      * @return Zend_Http_Client
0176      */
0177     public function setRawDataStream($data, $enctype = null)
0178     {
0179         $this->_streamingRequest = true;
0180         return $this->setRawData($data, $enctype);
0181     }
0182 
0183     /**
0184      * Same as Zend_Http_Client::setMethod() except it also creates an
0185      * Oauth specific reference to the method type.
0186      * Might be defunct and removed in a later iteration.
0187      *
0188      * @param  string $method
0189      * @return Zend_Http_Client
0190      */
0191     public function setMethod($method = self::GET)
0192     {
0193         if ($method == self::GET) {
0194             $this->setRequestMethod(self::GET);
0195         } elseif($method == self::POST) {
0196             $this->setRequestMethod(self::POST);
0197         } elseif($method == self::PUT) {
0198             $this->setRequestMethod(self::PUT);
0199         } elseif($method == self::DELETE) {
0200             $this->setRequestMethod(self::DELETE);
0201         } elseif($method == self::HEAD) {
0202             $this->setRequestMethod(self::HEAD);
0203         } elseif($method == self::OPTIONS) {
0204             $this->setRequestMethod(self::OPTIONS);
0205         }
0206         return parent::setMethod($method);
0207     }
0208 
0209     /**
0210      * Same as Zend_Http_Client::request() except just before the request is
0211      * executed, we automatically append any necessary OAuth parameters and
0212      * sign the request using the relevant signature method.
0213      *
0214      * @param  string $method
0215      * @return Zend_Http_Response
0216      */
0217     public function request($method = null)
0218     {
0219         if ($method !== null) {
0220             $this->setMethod($method);
0221         }
0222         $this->prepareOauth();
0223         return parent::request();
0224     }
0225 
0226     /**
0227      * Performs OAuth preparation on the request before sending.
0228      *
0229      * This primarily means taking a request, correctly encoding and signing
0230      * all parameters, and applying the correct OAuth scheme to the method
0231      * being used.
0232      *
0233      * @return void
0234      * @throws Zend_Oauth_Exception If POSTBODY scheme requested, but GET request method used; or if invalid request scheme provided
0235      */
0236     public function prepareOauth()
0237     {
0238         $requestScheme = $this->getRequestScheme();
0239         $requestMethod = $this->getRequestMethod();
0240         $query = null;
0241         if ($requestScheme == Zend_Oauth::REQUEST_SCHEME_HEADER) {
0242             $oauthHeaderValue = $this->getToken()->toHeader(
0243                 $this->getUri(true),
0244                 $this->_config,
0245                 $this->_getSignableParametersAsQueryString(),
0246                 $this->getRealm()
0247             );
0248             $this->setHeaders('Authorization', $oauthHeaderValue);
0249         } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_POSTBODY) {
0250             if ($requestMethod == self::GET) {
0251                 // require_once 'Zend/Oauth/Exception.php';
0252                 throw new Zend_Oauth_Exception(
0253                     'The client is configured to'
0254                     . ' pass OAuth parameters through a POST body but request method'
0255                     . ' is set to GET'
0256                 );
0257             }
0258             $raw = $this->getToken()->toQueryString(
0259                 $this->getUri(true),
0260                 $this->_config,
0261                 $this->_getSignableParametersAsQueryString()
0262             );
0263             $this->setRawData($raw, 'application/x-www-form-urlencoded');
0264             $this->paramsPost = array();
0265         } elseif ($requestScheme == Zend_Oauth::REQUEST_SCHEME_QUERYSTRING) {
0266             $params = $this->paramsGet;            
0267             $query = $this->getUri()->getQuery();
0268             if ($query) {
0269                 $queryParts = explode('&', $this->getUri()->getQuery());
0270                 foreach ($queryParts as $queryPart) {
0271                     $kvTuple = explode('=', $queryPart);
0272                     $params[urldecode($kvTuple[0])] =
0273                         (array_key_exists(1, $kvTuple) ? urldecode($kvTuple[1]) : null);
0274                 }
0275             }
0276             if (!empty($this->paramsPost)) {
0277                 $params = array_merge($params, $this->paramsPost);
0278                 $query  = $this->getToken()->toQueryString(
0279                     $this->getUri(true), $this->_config, $params
0280                 );
0281             }
0282             $query = $this->getToken()->toQueryString(
0283                 $this->getUri(true), $this->_config, $params
0284             );
0285             $this->getUri()->setQuery($query);
0286             $this->paramsGet = array();
0287         } else {
0288             // require_once 'Zend/Oauth/Exception.php';
0289             throw new Zend_Oauth_Exception('Invalid request scheme: ' . $requestScheme);
0290         }
0291     }
0292 
0293     /**
0294      * Collect all signable parameters into a single array across query string
0295      * and POST body. Don't include POST parameters if content type is multipart POST.
0296      *
0297      * @return array
0298      */
0299     protected function _getSignableParametersAsQueryString()
0300     {
0301         $params = array();
0302         if (!empty($this->paramsGet)) {
0303             $params = array_merge($params, $this->paramsGet);
0304         }
0305         if ($this->enctype != self::ENC_FORMDATA && !empty($this->paramsPost)) {
0306             $params = array_merge($params, $this->paramsPost);
0307         }
0308         return $params;
0309     }
0310 
0311     /**
0312      * Simple Proxy to the current Zend_Oauth_Config method. It's that instance
0313      * which holds all configuration methods and values this object also presents
0314      * as it's API.
0315      *
0316      * @param  string $method
0317      * @param  array $args
0318      * @return mixed
0319      * @throws Zend_Oauth_Exception if method does not exist in config object
0320      */
0321     public function __call($method, array $args)
0322     {
0323         if (!method_exists($this->_config, $method)) {
0324             // require_once 'Zend/Oauth/Exception.php';
0325             throw new Zend_Oauth_Exception('Method does not exist: ' . $method);
0326         }
0327         return call_user_func_array(array($this->_config,$method), $args);
0328     }
0329 }