]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - Zend/Oauth/Http.php
Release 6.5.0
[Github/sugarcrm.git] / Zend / Oauth / Http.php
1 <?php
2 /**
3  * Zend Framework
4  *
5  * LICENSE
6  *
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.
14  *
15  * @category   Zend
16  * @package    Zend_Oauth
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
19
20  */
21
22 /** Zend_Oauth_Http_Utility */
23 require_once 'Zend/Oauth/Http/Utility.php';
24
25 /** Zend_Uri_Http */
26 require_once 'Zend/Uri/Http.php';
27
28 /**
29  * @category   Zend
30  * @package    Zend_Oauth
31  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
32  * @license    http://framework.zend.com/license/new-bsd     New BSD License
33  */
34 class Zend_Oauth_Http
35 {
36     /**
37      * Array of all custom service parameters to be sent in the HTTP request
38      * in addition to the usual OAuth parameters.
39      *
40      * @var array
41      */
42     protected $_parameters = array();
43
44     /**
45      * Reference to the Zend_Oauth_Consumer instance in use.
46      *
47      * @var string
48      */
49     protected $_consumer = null;
50
51     /**
52      * OAuth specifies three request methods, this holds the current preferred
53      * one which by default uses the Authorization Header approach for passing
54      * OAuth parameters, and a POST body for non-OAuth custom parameters.
55      *
56      * @var string
57      */
58     protected $_preferredRequestScheme = null;
59
60     /**
61      * Request Method for the HTTP Request.
62      *
63      * @var string
64      */
65     protected $_preferredRequestMethod = Zend_Oauth::POST;
66
67     /**
68      * Instance of the general Zend_Oauth_Http_Utility class.
69      *
70      * @var Zend_Oauth_Http_Utility
71      */
72     protected $_httpUtility = null;
73
74     /**
75      * Constructor
76      *
77      * @param  Zend_Oauth_Consumer $consumer
78      * @param  null|array $parameters
79      * @param  null|Zend_Oauth_Http_Utility $utility
80      * @return void
81      */
82     public function __construct(
83         Zend_Oauth_Consumer $consumer, 
84         array $parameters = null,
85         Zend_Oauth_Http_Utility $utility = null
86     ) {
87         $this->_consumer = $consumer;
88         $this->_preferredRequestScheme = $this->_consumer->getRequestScheme();
89         if ($parameters !== null) {
90             $this->setParameters($parameters);
91         }
92         if ($utility !== null) {
93             $this->_httpUtility = $utility;
94         } else {
95             $this->_httpUtility = new Zend_Oauth_Http_Utility;
96         }
97     }
98
99     /**
100      * Set a preferred HTTP request method.
101      *
102      * @param  string $method
103      * @return Zend_Oauth_Http
104      */
105     public function setMethod($method)
106     {
107         if (!in_array($method, array(Zend_Oauth::POST, Zend_Oauth::GET))) {
108             require_once 'Zend/Oauth/Exception.php';
109             throw new Zend_Oauth_Exception('invalid HTTP method: ' . $method);
110         }
111         $this->_preferredRequestMethod = $method;
112         return $this;
113     }
114
115     /**
116      * Preferred HTTP request method accessor.
117      *
118      * @return string
119      */
120     public function getMethod()
121     {
122         return $this->_preferredRequestMethod;
123     }
124
125     /**
126      * Mutator to set an array of custom parameters for the HTTP request.
127      *
128      * @param  array $customServiceParameters
129      * @return Zend_Oauth_Http
130      */
131     public function setParameters(array $customServiceParameters)
132     {
133         $this->_parameters = $customServiceParameters;
134         return $this;
135     }
136
137     /**
138      * Accessor for an array of custom parameters.
139      *
140      * @return array
141      */
142     public function getParameters()
143     {
144         return $this->_parameters;
145     }
146
147     /**
148      * Return the Consumer instance in use.
149      *
150      * @return Zend_Oauth_Consumer
151      */
152     public function getConsumer()
153     {
154         return $this->_consumer;
155     }
156
157     /**
158      * Commence a request cycle where the current HTTP method and OAuth
159      * request scheme set an upper preferred HTTP request style and where
160      * failures generate a new HTTP request style further down the OAuth
161      * preference list for OAuth Request Schemes.
162      * On success, return the Request object that results for processing.
163      *
164      * @param  array $params
165      * @return Zend_Http_Response
166      * @throws Zend_Oauth_Exception on HTTP request errors
167      * @todo   Remove cycling?; Replace with upfront do-or-die configuration
168      */
169     public function startRequestCycle(array $params)
170     {
171         $response = null;
172         $body     = null;
173         $status   = null;
174         try {
175             $response = $this->_attemptRequest($params);
176         } catch (Zend_Http_Client_Exception $e) {
177             require_once 'Zend/Oauth/Exception.php';
178             throw new Zend_Oauth_Exception('Error in HTTP request', null, $e);
179         }
180         if ($response !== null) {
181             $body   = $response->getBody();
182             $status = $response->getStatus();
183         }
184         if ($response === null // Request failure/exception
185             || $status == 500  // Internal Server Error
186             || $status == 400  // Bad Request
187             || $status == 401  // Unauthorized
188             || empty($body)    // Missing token
189         ) {
190             $this->_assessRequestAttempt($response);
191             $response = $this->startRequestCycle($params);
192         }
193         return $response;
194     }
195
196     /**
197      * Return an instance of Zend_Http_Client configured to use the Query
198      * String scheme for an OAuth driven HTTP request.
199      *
200      * @param array $params
201      * @param string $url
202      * @return Zend_Http_Client
203      */
204     public function getRequestSchemeQueryStringClient(array $params, $url)
205     {
206         $client = Zend_Oauth::getHttpClient();
207         $client->setUri($url);
208         $client->getUri()->setQuery(
209             $this->_httpUtility->toEncodedQueryString($params)
210         );
211         $client->setMethod($this->_preferredRequestMethod);
212         return $client;
213     }
214
215     /**
216      * Manages the switch from OAuth request scheme to another lower preference
217      * scheme during a request cycle.
218      *
219      * @param  Zend_Http_Response
220      * @return void
221      * @throws Zend_Oauth_Exception if unable to retrieve valid token response
222      */
223     protected function _assessRequestAttempt(Zend_Http_Response $response = null)
224     {
225         switch ($this->_preferredRequestScheme) {
226             case Zend_Oauth::REQUEST_SCHEME_HEADER:
227                 $this->_preferredRequestScheme = Zend_Oauth::REQUEST_SCHEME_POSTBODY;
228                 break;
229             case Zend_Oauth::REQUEST_SCHEME_POSTBODY:
230                 $this->_preferredRequestScheme = Zend_Oauth::REQUEST_SCHEME_QUERYSTRING;
231                 break;
232             default:
233                 require_once 'Zend/Oauth/Exception.php';
234                 throw new Zend_Oauth_Exception(
235                     'Could not retrieve a valid Token response from Token URL:'
236                     . ($response !== null 
237                         ? PHP_EOL . $response->getBody()
238                         : ' No body - check for headers')
239                 );
240         }
241     }
242
243     /**
244      * Generates a valid OAuth Authorization header based on the provided
245      * parameters and realm.
246      *
247      * @param  array $params
248      * @param  string $realm
249      * @return string
250      */
251     protected function _toAuthorizationHeader(array $params, $realm = null)
252     {
253         $headerValue = array();
254         $headerValue[] = 'OAuth realm="' . $realm . '"';
255         foreach ($params as $key => $value) {
256             if (!preg_match("/^oauth_/", $key)) {
257                 continue;
258             }
259             $headerValue[] = Zend_Oauth_Http_Utility::urlEncode($key)
260                            . '="'
261                            . Zend_Oauth_Http_Utility::urlEncode($value)
262                            . '"';
263         }
264         return implode(",", $headerValue);
265     }
266 }