|
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 * @version $Id: Http.php 22662 2010-07-24 17:37:36Z mabe $ |
|
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 } |