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_Http_Utility */ 0023 // require_once 'Zend/Oauth/Http/Utility.php'; 0024 0025 /** Zend_Uri_Http */ 0026 // require_once 'Zend/Uri/Http.php'; 0027 0028 /** 0029 * @category Zend 0030 * @package Zend_Oauth 0031 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0032 * @license http://framework.zend.com/license/new-bsd New BSD License 0033 */ 0034 class Zend_Oauth_Http 0035 { 0036 /** 0037 * Array of all custom service parameters to be sent in the HTTP request 0038 * in addition to the usual OAuth parameters. 0039 * 0040 * @var array 0041 */ 0042 protected $_parameters = array(); 0043 0044 /** 0045 * Reference to the Zend_Oauth_Consumer instance in use. 0046 * 0047 * @var string 0048 */ 0049 protected $_consumer = null; 0050 0051 /** 0052 * OAuth specifies three request methods, this holds the current preferred 0053 * one which by default uses the Authorization Header approach for passing 0054 * OAuth parameters, and a POST body for non-OAuth custom parameters. 0055 * 0056 * @var string 0057 */ 0058 protected $_preferredRequestScheme = null; 0059 0060 /** 0061 * Request Method for the HTTP Request. 0062 * 0063 * @var string 0064 */ 0065 protected $_preferredRequestMethod = Zend_Oauth::POST; 0066 0067 /** 0068 * Instance of the general Zend_Oauth_Http_Utility class. 0069 * 0070 * @var Zend_Oauth_Http_Utility 0071 */ 0072 protected $_httpUtility = null; 0073 0074 /** 0075 * Constructor 0076 * 0077 * @param Zend_Oauth_Consumer $consumer 0078 * @param null|array $parameters 0079 * @param null|Zend_Oauth_Http_Utility $utility 0080 * @return void 0081 */ 0082 public function __construct( 0083 Zend_Oauth_Consumer $consumer, 0084 array $parameters = null, 0085 Zend_Oauth_Http_Utility $utility = null 0086 ) { 0087 $this->_consumer = $consumer; 0088 $this->_preferredRequestScheme = $this->_consumer->getRequestScheme(); 0089 if ($parameters !== null) { 0090 $this->setParameters($parameters); 0091 } 0092 if ($utility !== null) { 0093 $this->_httpUtility = $utility; 0094 } else { 0095 $this->_httpUtility = new Zend_Oauth_Http_Utility; 0096 } 0097 } 0098 0099 /** 0100 * Set a preferred HTTP request method. 0101 * 0102 * @param string $method 0103 * @return Zend_Oauth_Http 0104 */ 0105 public function setMethod($method) 0106 { 0107 if (!in_array($method, array(Zend_Oauth::POST, Zend_Oauth::GET))) { 0108 // require_once 'Zend/Oauth/Exception.php'; 0109 throw new Zend_Oauth_Exception('invalid HTTP method: ' . $method); 0110 } 0111 $this->_preferredRequestMethod = $method; 0112 return $this; 0113 } 0114 0115 /** 0116 * Preferred HTTP request method accessor. 0117 * 0118 * @return string 0119 */ 0120 public function getMethod() 0121 { 0122 return $this->_preferredRequestMethod; 0123 } 0124 0125 /** 0126 * Mutator to set an array of custom parameters for the HTTP request. 0127 * 0128 * @param array $customServiceParameters 0129 * @return Zend_Oauth_Http 0130 */ 0131 public function setParameters(array $customServiceParameters) 0132 { 0133 $this->_parameters = $customServiceParameters; 0134 return $this; 0135 } 0136 0137 /** 0138 * Accessor for an array of custom parameters. 0139 * 0140 * @return array 0141 */ 0142 public function getParameters() 0143 { 0144 return $this->_parameters; 0145 } 0146 0147 /** 0148 * Return the Consumer instance in use. 0149 * 0150 * @return Zend_Oauth_Consumer 0151 */ 0152 public function getConsumer() 0153 { 0154 return $this->_consumer; 0155 } 0156 0157 /** 0158 * Commence a request cycle where the current HTTP method and OAuth 0159 * request scheme set an upper preferred HTTP request style and where 0160 * failures generate a new HTTP request style further down the OAuth 0161 * preference list for OAuth Request Schemes. 0162 * On success, return the Request object that results for processing. 0163 * 0164 * @param array $params 0165 * @return Zend_Http_Response 0166 * @throws Zend_Oauth_Exception on HTTP request errors 0167 * @todo Remove cycling?; Replace with upfront do-or-die configuration 0168 */ 0169 public function startRequestCycle(array $params) 0170 { 0171 $response = null; 0172 $body = null; 0173 $status = null; 0174 try { 0175 $response = $this->_attemptRequest($params); 0176 } catch (Zend_Http_Client_Exception $e) { 0177 // require_once 'Zend/Oauth/Exception.php'; 0178 throw new Zend_Oauth_Exception('Error in HTTP request', null, $e); 0179 } 0180 if ($response !== null) { 0181 $body = $response->getBody(); 0182 $status = $response->getStatus(); 0183 } 0184 if ($response === null // Request failure/exception 0185 || $status == 500 // Internal Server Error 0186 || $status == 400 // Bad Request 0187 || $status == 401 // Unauthorized 0188 || empty($body) // Missing token 0189 ) { 0190 $this->_assessRequestAttempt($response); 0191 $response = $this->startRequestCycle($params); 0192 } 0193 return $response; 0194 } 0195 0196 /** 0197 * Return an instance of Zend_Http_Client configured to use the Query 0198 * String scheme for an OAuth driven HTTP request. 0199 * 0200 * @param array $params 0201 * @param string $url 0202 * @return Zend_Http_Client 0203 */ 0204 public function getRequestSchemeQueryStringClient(array $params, $url) 0205 { 0206 $client = Zend_Oauth::getHttpClient(); 0207 $client->setUri($url); 0208 $client->getUri()->setQuery( 0209 $this->_httpUtility->toEncodedQueryString($params) 0210 ); 0211 $client->setMethod($this->_preferredRequestMethod); 0212 return $client; 0213 } 0214 0215 /** 0216 * Manages the switch from OAuth request scheme to another lower preference 0217 * scheme during a request cycle. 0218 * 0219 * @param Zend_Http_Response 0220 * @return void 0221 * @throws Zend_Oauth_Exception if unable to retrieve valid token response 0222 */ 0223 protected function _assessRequestAttempt(Zend_Http_Response $response = null) 0224 { 0225 switch ($this->_preferredRequestScheme) { 0226 case Zend_Oauth::REQUEST_SCHEME_HEADER: 0227 $this->_preferredRequestScheme = Zend_Oauth::REQUEST_SCHEME_POSTBODY; 0228 break; 0229 case Zend_Oauth::REQUEST_SCHEME_POSTBODY: 0230 $this->_preferredRequestScheme = Zend_Oauth::REQUEST_SCHEME_QUERYSTRING; 0231 break; 0232 default: 0233 // require_once 'Zend/Oauth/Exception.php'; 0234 throw new Zend_Oauth_Exception( 0235 'Could not retrieve a valid Token response from Token URL:' 0236 . ($response !== null 0237 ? PHP_EOL . $response->getBody() 0238 : ' No body - check for headers') 0239 ); 0240 } 0241 } 0242 0243 /** 0244 * Generates a valid OAuth Authorization header based on the provided 0245 * parameters and realm. 0246 * 0247 * @param array $params 0248 * @param string $realm 0249 * @return string 0250 */ 0251 protected function _toAuthorizationHeader(array $params, $realm = null) 0252 { 0253 $headerValue = array(); 0254 $headerValue[] = 'OAuth realm="' . $realm . '"'; 0255 foreach ($params as $key => $value) { 0256 if (!preg_match("/^oauth_/", $key)) { 0257 continue; 0258 } 0259 $headerValue[] = Zend_Oauth_Http_Utility::urlEncode($key) 0260 . '="' 0261 . Zend_Oauth_Http_Utility::urlEncode($value) 0262 . '"'; 0263 } 0264 return implode(",", $headerValue); 0265 } 0266 }